home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / OpenDoc / PictPart / Source ƒ / CPPictPart.cpp next >
Encoding:
C/C++ Source or Header  |  1995-04-28  |  106.5 KB  |  3,593 lines  |  [TEXT/MPCC]

  1. /*
  2.     File:        CPPictPart.cpp
  3.  
  4.     Contains:    CPPictPart OpenDoc part editor class implementation.
  5.                 Built using PartMaker , then modified.
  6.  
  7.     Owned by:    Pierre-François BESSON / ORKIS
  8.  
  9.     Copyright:    © 1995 by ORKIS S.A., all rights reserved.
  10.         partly :© 1995 by Apple Computer, Inc., all rights reserved.
  11.  
  12.     Change History (most recent first):
  13.     
  14.     <5>    4/14/95    JS        Updated for Developer Release 2
  15.     <4>    3/8/95    JS        Updated to b1c13/c14
  16.     <3>    3/8/95    RA        Add tokenized kODPresDefault param to RegisterWindow().
  17.     <2>    2/21/95    RA        Add kODFrameObject param to RegisterWindow().
  18.     <1>    2/2/95    RA        first checked in
  19.     <0>    PartMaker source by E, Soldan, T. Çelik, J. Alfke, R. Adkins, J. Schalk
  20. */
  21.  
  22. #ifndef ODDebug
  23. #define ODDebug 0
  24. #endif
  25.  
  26.  
  27. #ifndef _ALTPOINT_
  28. #include <AltPoint.h>
  29. #endif
  30.  
  31. #ifndef _EXCEPT_
  32. #include <Except.h>
  33. #endif
  34.  
  35. #ifndef SOM_Module_OpenDoc_Global_TypesB_defined
  36. #include "ODTypesB.xh"
  37. #endif
  38.  
  39. #ifndef _CPPICTPART_
  40. #include "CPPictPart.h"
  41. #endif
  42.  
  43. #ifndef _PARTUTILS_
  44. #include "PartUtils.h"
  45. #endif
  46.  
  47. #ifndef _PICTPARTDEF_
  48. #include "PictPartDef.h"
  49. #endif
  50.  
  51. #ifndef _USERSRCM_
  52. #include <UseRsrcM.h>
  53. #endif
  54.  
  55. #ifndef _INFOUTIL_
  56. #include <InfoUtil.h>
  57. #endif
  58.  
  59. #ifndef _ITEXT_
  60. #include <IText.h>
  61. #endif
  62.  
  63. #ifndef SOM_ODDraft_xh
  64. #include <Draft.xh>
  65. #endif
  66.  
  67. #ifndef SOM_ODArbitrator_xh
  68. #include <Arbitrat.xh>
  69. #endif
  70.  
  71. #ifndef SOM_ODCanvas_xh
  72. #include <Canvas.xh>
  73. #endif
  74.  
  75. #ifndef SOM_ODPart_xh
  76. #include <Part.xh>
  77. #endif
  78.  
  79. #ifndef SOM_ODFacet_xh
  80. #include <Facet.xh>
  81. #endif
  82.  
  83. #ifndef SOM_ODFrame_xh
  84. #include <Frame.xh>
  85. #endif
  86.  
  87. #ifndef SOM_ODFrameFacetIterator_xh
  88. #include <FrFaItr.xh>
  89. #endif
  90.  
  91. #ifndef SOM_ODFoci_xh
  92. #include <Foci.xh>
  93. #endif
  94.  
  95. #ifndef SOM_ODInfo_xh
  96. #include <Info.xh>
  97. #endif
  98.  
  99. #ifndef SOM_ODLink_xh
  100. #include <Link.xh>
  101. #endif
  102.  
  103. #ifndef SOM_ODBaseLink_xh
  104. #include <LinkB.xh>
  105. #endif
  106.  
  107. #ifndef SOM_ODLinkSpec_xh
  108. #include <LinkSpec.xh>
  109. #endif
  110.  
  111. #ifndef SOM_ODBaseLinkSpec_xh
  112. #include <LinkSpcB.xh>
  113. #endif
  114.  
  115. #ifndef SOM_ODLinkSource_xh
  116. #include <LinkSrc.xh>
  117. #endif
  118.  
  119. #ifndef SOM_ODBaseLinkSource_xh
  120. #include <LinkSrcB.xh>
  121. #endif
  122.  
  123. #ifndef SOM_ODPstObj_
  124. #include <PstObj.xh>
  125. #endif
  126.  
  127. #ifndef SOM_ODShape_xh
  128. #include <Shape.xh>
  129. #endif
  130.  
  131. #ifndef SOM_ODStdProps_xh
  132. #include <StdProps.xh>
  133. #endif
  134.  
  135. #ifndef SOM_ODStdTypes_xh
  136. #include <StdTypes.xh>
  137. #endif
  138.  
  139. #ifndef SOM_ODDragAndDrop_xh
  140. #include <DragDrp.xh>
  141. #endif
  142.  
  143. #ifndef SOM_ODDragItemIterator_xh
  144. #include <DgItmIt.xh>
  145. #endif
  146.  
  147. #ifndef SOM_ODClipboard_xh
  148. #include <Clipbd.xh>
  149. #endif
  150.  
  151. #ifndef _STDDEFS_
  152. #include <StdDefs.xh>
  153. #endif
  154.  
  155. #ifndef _PLFMDEF_
  156. #include <PlfmDef.h>
  157. #endif
  158.  
  159. #ifndef SOM_ODCmdDefs_xh
  160. #include <CmdDefs.xh>
  161. #endif
  162.  
  163. #ifndef SOM_ODStorageU_xh
  164. #include <StorageU.xh>
  165. #endif
  166.  
  167. #ifndef SOM_ODStorageUnitView_xh
  168. #include <SUView.xh>
  169. #endif
  170.  
  171. #ifndef SOM_ODTrnsform_xh
  172. #include <Trnsform.xh>
  173. #endif
  174.  
  175. #ifndef SOM_ODFocusSet_xh
  176. #include <FocusSet.xh>
  177. #endif
  178.  
  179. #ifndef SOM_ODFoci_xh
  180. #include <Foci.xh>
  181. #endif
  182.  
  183. #ifndef SOM_ODMenuBar_xh
  184. #include <MenuBar.xh>
  185. #endif
  186.  
  187. #ifndef SOM_ODWindow_xh
  188. #include <Window.xh>
  189. #endif
  190.  
  191. #ifndef SOM_ODWinStat_xh
  192. #include <WinStat.xh>
  193. #endif
  194.  
  195. #ifndef SOM_ODSession_xh
  196. #include <ODSessn.xh>
  197. #endif
  198.  
  199. #ifndef _PASCLSTR_
  200. #include <PasclStr.h>
  201. #endif
  202.  
  203. #ifndef _FOCUSLIB_
  204. #include <FocusLib.h>
  205. #endif
  206.  
  207. #ifndef __ERRORS__
  208. #include <Errors.h>
  209. #endif
  210.  
  211. #ifndef __RESOURCES__
  212. #include <Resources.h>
  213. #endif
  214.  
  215. #ifndef __DIALOGS__
  216. #include <Dialogs.h>
  217. #endif
  218.  
  219. #ifndef __TOOLUTILS__
  220. #include <ToolUtils.h>
  221. #endif
  222.  
  223. #ifndef _STORUTIL_
  224. #include <StorUtil.h>
  225. #endif
  226.  
  227. #ifndef _STDTYPIO_
  228. #include "StdTypIO.h"
  229. #endif
  230.  
  231. #include <Memory.h>
  232. #include <StandardFile.h>
  233. #include <Files.h>
  234. #include <Events.h>
  235. #include <Drag.h>
  236. #include <ImageCompression.h>
  237. #ifndef _BARRAY_
  238. #include <BArray.h>
  239. #endif
  240. #ifndef _ISOSTR_
  241. #include "ISOStr.h"
  242. #endif
  243.  
  244. // ISOString equivalents for Apple scrap types
  245. #define        kODApplePICT    "Apple:OSType:Scrap:PICT"
  246. #define        kODApplehfs        "Apple:OSType:Scrap:hfs "
  247.  
  248. const ODPropertyName    kPPPropPartInfo        = "PictPart:Property:PartInfo";
  249. const ODPropertyName    kPPPropSourceLink    = "PictPart:Property:SourceLink";
  250. const ODPropertyName    kPPPropDestLink        = "PictPart:Property:DestLink";
  251. const ODValueType          kPictPartValue         = "PictPart:Value";
  252.  
  253. const ODType kPictNormalFacette =  "PictPart:Presentation:Normal";
  254. const ODType kPictToolsFacette = "PictPart:Presentation:Palette";
  255.  
  256.  
  257. //========================================================================================
  258. // Miscellaneous
  259. //========================================================================================
  260.  
  261. #define qDebug 0
  262.  
  263. #if qDebug
  264.     #define     WeBeHere(s) DebugStr((StringPtr)s)
  265. #else
  266.     #define     WeBeHere(s)
  267. #endif
  268.  
  269.  
  270. #ifdef applec
  271. #pragma segment PictPart
  272. #endif
  273.  
  274.  
  275. ODSession* gSession = kODNULL;
  276.  
  277.  
  278.  
  279. //========================================================================================
  280. // Constants
  281. //========================================================================================
  282.  
  283.  
  284.  
  285. const short kContentStringResID = 5000;
  286. const short kContentStringID    = 1;
  287. const short kAboutTextID        = 2;
  288.  
  289. // PictParts special
  290. const short kShowPaletteID      = 3;
  291. const short kHidePaletteID      = 4;
  292. const short toolIconWidth = 32;
  293. const short toolIconHeight = 20;
  294.  
  295.  
  296.  
  297. //========================================================================================
  298. // CPPictPart
  299. //========================================================================================
  300.  
  301.  
  302.  
  303. //----------------------------------------------------------------------------------------
  304. // CPPictPart::CPPictPart
  305. //----------------------------------------------------------------------------------------
  306.  
  307. CPPictPart::CPPictPart()
  308. {
  309.     WeBeHere("\pCPPictPart::CPPictPart");
  310.  
  311.     fDirty    = kODFalse;
  312.     fWindowID = 0;
  313.     fSession  = kODNULL;
  314.     fMenuBar  = kODNULL;
  315.  
  316.     fDraftKey = 0;
  317.     fScopeFrame = kODNULL;
  318.     
  319.     // Note that fDisplayFrames is a static field, and therefore
  320.     // its constructor is automatically called before
  321.     // CPPictPart constructor.
  322.  
  323.     // PFB
  324.  
  325.     fClipboardChangeID = -1;
  326.     fSrcLink = kODNULL;
  327.     fSrcLinkChange = kODUnknownChange;
  328.     fDestLink = kODNULL;
  329.     fDraft = kODNULL;
  330.  
  331.     fPicture = nil;
  332.     
  333.     fCurrentCursorHandle = nil;
  334.     fMouseInsideActiveFrame = kODFalse;
  335.     fExternalizeOnlyPICTFormat = kODFalse;
  336.     
  337.     fPaletteIsOpen = kODFalse;
  338.     fPaletteWindow = nil;
  339.     fCurrentTool = arrowTool;
  340. }
  341.  
  342. //----------------------------------------------------------------------------------------
  343. // CPPictPart::~CPPictPart
  344. //----------------------------------------------------------------------------------------
  345.  
  346. CPPictPart::~CPPictPart()
  347. {
  348.     WeBeHere("\pCPPictPart::~CPPictPart");
  349.  
  350.     // PFB
  351.     if( fPicture != nil )
  352.         DisposeHandle( fPicture );
  353.     fPicture = nil;
  354.     if( fCurrentCursorHandle != nil )
  355.         DisposeHandle( (Handle)fCurrentCursorHandle );
  356.     fCurrentCursorHandle = nil;
  357. }
  358.  
  359. //----------------------------------------------------------------------------------------
  360. // CPPictPart::InitPart
  361. //----------------------------------------------------------------------------------------
  362.  
  363. void CPPictPart::InitPart(Environment* ev, ODStorageUnit* storageUnit, ODPart* partWrapper)
  364.  
  365. // Called by the draft object.
  366.  
  367. {
  368.     WeBeHere("\pCPPictPart::InitPart");
  369.  
  370.     fSelf = partWrapper;        // Will very much need this later.
  371.     fStorageUnit = storageUnit;
  372.  
  373.     this->MyCommonInitPart(ev);        // We say "this" everywhere just to be explicit.
  374.  
  375.     ODStorageUnit *pictPartContentSU;
  376.     
  377.     pictPartContentSU = storageUnit->AddProperty(ev, kODPropContents);
  378.     pictPartContentSU->AddValue(ev, kPictPartKind);
  379.     pictPartContentSU->AddValue(ev, kODApplePICT);
  380.         // For your edification, AddProperty & AddValue
  381.         // implicitly focus.  Check the API for more info.
  382.  
  383.     {
  384.         CUsingLibraryResources fil;
  385.         fPicture = ::GetResource( bkgndPictureRsrcType, bkgndPictureRsrcId );
  386.         if( fPicture == nil )
  387.             DebugStr("\pcannot load picture resource !!!");
  388.         else
  389.             ::DetachResource( fPicture );
  390.     }        // Use CUsingLibraryResources to use your part's resource fork.
  391.             // Make it go out of scope when you are done.
  392.             // We are creating our part's initial content here.
  393.  
  394.  
  395.     // Initialize your other fields here.
  396.  
  397.     fDirty = kODTrue;
  398. }
  399.  
  400. //----------------------------------------------------------------------------------------
  401. // CPPictPart::InitPartFromStorage
  402. //----------------------------------------------------------------------------------------
  403.  
  404. void CPPictPart::InitPartFromStorage(Environment* ev, ODStorageUnit* storageUnit, ODPart* partWrapper)
  405.  
  406. // Called by the draft object.
  407.  
  408. {
  409.     WeBeHere("\pCPPictPart::InitPartFromStorage");
  410.  
  411.     fSelf = partWrapper;        // Will very much need this later.
  412.     fStorageUnit = storageUnit;
  413.  
  414.     this->MyCommonInitPart(ev);
  415.  
  416.     ODStorageUnitRef    weakRef;
  417.     ODULong                size;
  418.  
  419.     // Internalize the part's display frame list.
  420.  
  421.     if (ODSUExistsThenFocus(ev, storageUnit, kODPropDisplayFrames, kODWeakStorageUnitRefs ))
  422.     {                                    
  423.         size = storageUnit->GetSize(ev);
  424.         storageUnit->SetOffset(ev, 0);    
  425.     
  426.         for ( ODULong offset = 0; offset < size; offset += 4 )
  427.         {        
  428.             StorageUnitGetValue(storageUnit, ev, sizeof(ODStorageUnitRef), weakRef);
  429.             
  430.             if ( storageUnit->IsValidStorageUnitRef(ev, weakRef) )
  431.             {        
  432.                 ODFrame *frame = storageUnit->GetDraft(ev)->
  433.                             GetFrame(ev, storageUnit->GetIDFromStorageUnitRef(ev, weakRef));
  434.                 fDisplayFrames.Add(frame);
  435.             }
  436.         }
  437.     }
  438.  
  439.     // PFB
  440.     InternalizeFromSU( ev, storageUnit, kODNULL );
  441.  
  442.     //
  443.     // Read in the source and destination links
  444.     //
  445.      ODStorageUnitRef aSURef;
  446.  
  447.     if ( fStorageUnit->Exists(ev, kPPPropSourceLink, kPictPartKind, 0) )
  448.         {
  449.         ODBoolean validLink = kODTrue;
  450.         fStorageUnit->Focus(ev, kPPPropSourceLink, kODPosUndefined, kPictPartKind, 0, kODPosUndefined);
  451.         TRY
  452.             StorageUnitGetValue(fStorageUnit, ev, sizeof(ODStorageUnitRef),&aSURef);
  453.             if ( fStorageUnit->IsValidStorageUnitRef(ev, aSURef) )
  454.             {
  455.                 fSrcLink = fDraft->GetLinkSource(ev, fStorageUnit->GetIDFromStorageUnitRef(ev, aSURef));
  456.                 StorageUnitGetValue(fStorageUnit, ev, sizeof(ODChangeID), (ODValue) &fSrcLinkChange );
  457.  
  458.                 // Ensure the link source references this part
  459.                 fSrcLink->SetSourcePart(ev, fStorageUnit );
  460.             }
  461.             else
  462.             {
  463.                 validLink = kODFalse;
  464.             }
  465.         CATCH_ALL
  466.             validLink = kODFalse;
  467.         ENDTRY
  468.  
  469.         if ( !validLink )
  470.             {
  471.             fStorageUnit->SetOffset(ev, 0);
  472.             fStorageUnit->DeleteValue(ev, fStorageUnit->GetSize(ev));
  473.             fSrcLink = kODNULL;
  474.             }
  475.         }
  476.  
  477.     if ( fStorageUnit->Exists(ev, kPPPropDestLink, kPictPartKind, 0) )
  478.         {
  479.         ODBoolean validLink = kODTrue;
  480.         fStorageUnit->Focus(ev, kPPPropDestLink, kODPosUndefined, kPictPartKind, 0, kODPosUndefined);
  481.         TRY
  482.             StorageUnitGetValue(fStorageUnit, ev, sizeof(ODStorageUnitRef),&aSURef);
  483.             if ( fStorageUnit->IsValidStorageUnitRef(ev, aSURef) )
  484.                 {
  485.                 fDestLink = fDraft->GetLink(ev, fStorageUnit->GetIDFromStorageUnitRef(ev, aSURef), (ODLinkSpec*) kODNULL);
  486.                 StorageUnitGetValue(fStorageUnit, ev, sizeof(ODLinkInfo), (ODValue) &fDestLinkInfo);
  487.                 ODType kind = (ODType) ODNewPtr((ODULong) fDestLinkInfo.kind , kDefaultHeapID);
  488.                 StorageUnitGetValue(fStorageUnit, ev, (ODULong) fDestLinkInfo.kind, (ODValue) kind);
  489.                 fDestLinkInfo.kind = kind;
  490.     
  491.                 // Now register as a dependent of the link
  492.                 // Specify kODUnknownChange to force getting the text.
  493.                 // By default the destination is automatically updated.
  494.                 if( fDestLinkInfo.autoUpdate )
  495.                     fDestLink->RegisterDependent(ev, fSelf, kODUnknownChange);
  496.                 fDraft->SetChangedFromPrev(ev);
  497.                 }
  498.             else
  499.                 {
  500.                 validLink = kODFalse;
  501.                 }
  502.         CATCH_ALL
  503.             validLink = kODFalse;
  504.         ENDTRY
  505.  
  506.         if ( !validLink )
  507.             {
  508.             fStorageUnit->SetOffset(ev, 0);
  509.             fStorageUnit->DeleteValue(ev, fStorageUnit->GetSize(ev));
  510.             fDestLink = kODNULL;
  511.             }
  512.         }
  513.  
  514. }
  515.  
  516. //----------------------------------------------------------------------------------------
  517. // CPPictPart::MyCommonInitPart
  518. //----------------------------------------------------------------------------------------
  519.  
  520. void CPPictPart::MyCommonInitPart(Environment* ev)
  521. {
  522.     WeBeHere("\pCPPictPart::MyCommonInitPart");
  523.  
  524.     fSession = fStorageUnit->GetSession(ev);
  525.         // As your part grows, add your initialization that is common
  526.         // between InitPart and InitPartFromStorage here.
  527.         // Note that GetStorageUnit can be used, since just prior to
  528.         // calling this method, InitPart calledInitPersistentObject or
  529.         // InitPartFromStorage called InitPersistentObjectFromStorage.
  530.  
  531.     fSelectionFocus = fSession->Tokenize(ev, kODSelectionFocus);
  532.     fMenuFocus      = fSession->Tokenize(ev, kODMenuFocus);
  533.     fKeyFocus       = fSession->Tokenize(ev, kODKeyFocus);
  534.     fModalFocus     = fSession->Tokenize(ev, kODModalFocus);
  535.  
  536.     fFocusSet = fSession->GetArbitrator(ev)->CreateFocusSet(ev);
  537.     fFocusSet->Add(ev, fKeyFocus);
  538.     fFocusSet->Add(ev, fMenuFocus);
  539.     fFocusSet->Add(ev, fSelectionFocus);
  540.  
  541.     fMenuBar = fSession->GetWindowState(ev)->CopyBaseMenuBar(ev);
  542.  
  543.     {
  544.         CUsingLibraryResources fil;
  545.         fMenu = ::GetMenu(kMenuID);
  546.         if (fMenu)
  547.             ::DetachResource((Handle)fMenu);        // Must detach it!
  548.     }
  549.  
  550.     if (!fMenu)
  551.         DebugStr("\pCPPictPart::MyCommonMyInitPart -- couldn't create menu.");
  552.             // We are using debug messages
  553.             // for these types of errors.  When SOM is available, this issue
  554.             // will be addressed correctly.
  555.  
  556.  
  557.     fMenuBar->AddMenuLast(ev, kMenuID, fMenu, fSelf);
  558.  
  559.     // PFB
  560.     fDraft = fStorageUnit->GetDraft(ev);
  561.  
  562.     fPictNormalPresentation = fSession->Tokenize( ev, kPictNormalFacette );
  563.     fPictToolsPresentation = fSession->Tokenize(ev,kPictToolsFacette);
  564.  
  565.     fMenuBar->RegisterCommand( ev, kPictPart_PaletteStuff, kMenuID, 1 );
  566.     fMenuBar->RegisterCommand( ev, kPictPart_ZoomInCmd, kMenuID, 3 );
  567.     fMenuBar->RegisterCommand( ev, kPictPart_ZoomOutCmd, kMenuID, 4 );
  568.     fMenuBar->RegisterCommand( ev, kPictPart_ExtOnlyPICT, kMenuID, 6 );
  569.  
  570. }
  571.  
  572. //----------------------------------------------------------------------------------------
  573. // CPPictPart::Externalize
  574. //----------------------------------------------------------------------------------------
  575.  
  576. void    CPPictPart::Externalize(Environment* ev)
  577. {
  578.     WeBeHere("\pCPPictPart::Externalize");
  579.  
  580.     if (fDirty != kODFalse)
  581.         {
  582.         ODSUForceFocus(ev, fStorageUnit, kODPropDisplayFrames, kODWeakStorageUnitRefs);
  583.             // Externalize the part's display frame list.
  584.         
  585.         fStorageUnit->Remove(ev);
  586.         fStorageUnit->AddValue(ev, kODWeakStorageUnitRefs);
  587.             // Persistent object references are stored in a side table, rather than
  588.             // in the property/value stream. Thus, deleting the contents of a value
  589.             // will not "delete" the references previously written to that value. To
  590.             // completely "delete" all references written to the value, we must
  591.             // remove the value and add it back.
  592.  
  593.         for (FrameLink *fl = fDisplayFrames.First(); fl->Frame(); fl = fl->Next())
  594.         {
  595.             ODStorageUnitRef    weakRef;
  596.             ODID                frameID;
  597.  
  598.             frameID = fl->Frame()->GetID(ev);
  599.             if ( fDraftKey )
  600.                 frameID =  fSelf->GetStorageUnit(ev)->GetDraft(ev)
  601.                                 ->WeakClone(ev, fDraftKey, frameID, 0, 
  602.                                     fScopeFrame ? fScopeFrame->GetID(ev) : 0);
  603.                 
  604.             fStorageUnit->GetWeakStorageUnitRef(ev, frameID, weakRef);
  605.             StorageUnitSetValue(fStorageUnit, ev, sizeof(ODStorageUnitRef), weakRef);
  606.         }
  607.         
  608.  
  609.         // PFB
  610.         PrepareSU( ev, fStorageUnit );
  611.         ExternalizeToSU( ev, fStorageUnit, kODNULL );
  612.  
  613.         //
  614.         // Write out the source and destination links
  615.         //
  616.         ODStorageUnitRef    aSURef;
  617.  
  618.  
  619.         if ( fSrcLink == kODNULL)
  620.             {
  621.             if ( fStorageUnit->Exists(ev, kPPPropSourceLink, kPictPartKind, 0) )
  622.                 {
  623.                 fStorageUnit->Focus(ev, kPPPropSourceLink, kODPosUndefined, kPictPartKind, (ODValueIndex)0, kODPosUndefined);
  624.                 fStorageUnit->Remove(ev);
  625.                 }
  626.             }
  627.         else
  628.             {
  629.             fSrcLink->Externalize(ev);
  630.             if ( fStorageUnit->Exists(ev, kPPPropSourceLink, kPictPartKind, 0) )
  631.                 fStorageUnit->Focus(ev, kPPPropSourceLink, kODPosUndefined, kPictPartKind, (ODValueIndex)0, kODPosUndefined);
  632.             else
  633.                 fStorageUnit->AddProperty(ev,kPPPropSourceLink)->AddValue(ev,kPictPartKind);
  634.             fStorageUnit->GetStrongStorageUnitRef(ev, fSrcLink->GetStorageUnit(ev)->GetID(ev), aSURef);
  635.             StorageUnitSetValue( fStorageUnit, ev, sizeof(ODStorageUnitRef), aSURef);
  636.             }
  637.     
  638.         if ( fDestLink == kODNULL)
  639.         {
  640.             if ( fStorageUnit->Exists(ev, kPPPropDestLink, kPictPartKind, 0) )
  641.                 {
  642.                 fStorageUnit->Focus(ev, kPPPropDestLink, kODPosUndefined, kPictPartKind, (ODValueIndex)0, kODPosUndefined);
  643.                 fStorageUnit->Remove(ev);
  644.                 }
  645.         }
  646.         else 
  647.         {
  648.             fDestLink->Externalize(ev);
  649.             if ( fStorageUnit->Exists(ev, kPPPropDestLink, kPictPartKind, 0) )
  650.                 fStorageUnit->Focus(ev, kPPPropDestLink, kODPosUndefined, kPictPartKind, (ODValueIndex)0, kODPosUndefined);
  651.             else
  652.                 fStorageUnit->AddProperty(ev,kPPPropDestLink)->AddValue(ev,kPictPartKind);
  653.             fStorageUnit->GetStrongStorageUnitRef(ev, fDestLink->GetStorageUnit(ev)->GetID(ev), aSURef);
  654.             StorageUnitSetValue(fStorageUnit, ev, sizeof(ODStorageUnitRef), aSURef);
  655.     
  656.             // store dest link info kind as ISOStr
  657.             ODType saveKind = fDestLinkInfo.kind;
  658.             fDestLinkInfo.kind = (ODType) ODISOStrLength(saveKind) + 1;
  659.             StorageUnitSetValue(fStorageUnit, ev, sizeof(ODLinkInfo), (ODValue) &fDestLinkInfo );
  660.             StorageUnitSetValue(fStorageUnit, ev, (ODULong)fDestLinkInfo.kind, (ODValue) saveKind );
  661.             fDestLinkInfo.kind = saveKind;
  662.         }
  663.  
  664.         fDirty = kODFalse;
  665.             // Flag our part as no longer being dirty.
  666.     }
  667. }
  668.  
  669. //----------------------------------------------------------------------------------------
  670. // CPPictPart::MySetDirty
  671. //----------------------------------------------------------------------------------------
  672.  
  673. void CPPictPart::MySetDirty(Environment* ev)
  674. {
  675.  
  676.     WeBeHere("\pCPPictPart::MySetDirty");
  677.  
  678.     fDirty = kODTrue;
  679.     fStorageUnit->GetDraft(ev)->SetChangedFromPrev(ev);
  680.     fSrcLinkChange = fSession->UniqueChangeID(ev);
  681.  
  682. }
  683.  
  684. //----------------------------------------------------------------------------------------
  685. // CPPictPart::Purge
  686. //----------------------------------------------------------------------------------------
  687.  
  688. ODSize CPPictPart::Purge(Environment* ev, ODSize size)
  689. {
  690. ODUnused(size);
  691.     WeBeHere("\pCPPictPart::Purge");
  692.  
  693.     // CPPictPart doesn't do anything here.
  694.  
  695.     return 0;
  696. }
  697.  
  698. //----------------------------------------------------------------------------------------
  699. // CPPictPart::Release
  700. //----------------------------------------------------------------------------------------
  701.  
  702. void CPPictPart::Release(Environment* ev)
  703. {
  704.     WeBeHere("\pCPPictPart::Release");
  705.  
  706.     // If you are using RegisterIdle on the part, not on frames, then
  707.     // the RefCount is bumped up by one by OpenDoc.  OpenDoc keeps a
  708.     // reference to all parts that register idle time.  ALL OF THESE MUST
  709.     // BE RESOLVED BEFORE THE DESTRUCTOR IS CALLED.  This is
  710.     // the place to do that.
  711.  
  712.     // The logic below, assuming that CPPictPart has registered for idle
  713.     // time, is that if the RefCount is 1, then we are here to unregister
  714.     // the idle.  When the part is being removed, OpenDoc must decrement
  715.     // the RefCount and call Release until the part gets messaged with
  716.     // a RefCount of 0.  Once you return from here with a RefCount of 0,
  717.     // OpenDoc will call the destructor.
  718.  
  719.     // This means that if you have registered for idle time, Release will
  720.     // be called TWICE when closing down your part.  The first time the
  721.     // RefCount is 1.  This is when you should unregister the idle time.
  722.     // When you are called with a RefCount of 0, that when it gets really
  723.     // serious.  This is when you detach from the draft.
  724.  
  725.     if (fSelf->GetRefCount(ev) == 1) {
  726.         // Here is where you would unregister idle time for the part if
  727.         // have registered time.  Note that if you unregister without
  728.         // registering, OpenDoc will crash.  It's not just a simple
  729.         // look-up-and-if-there-remove kind of operation.
  730.  
  731.         // Note that if you unregister idle here, OpenDoc will need to
  732.         // call Release (here) due to it.  This means that when we call
  733.         // to unregister the idle, we are nesting calls to Release.
  734.         // Due to this, I return out of each case, just to make the
  735.         // flow of control of the call(s) to Release more straightforward.
  736.  
  737.         // Note that if you are going to use idle registration, you will
  738.         // need to include "Disptch.h"
  739.  
  740.         return;
  741.     }
  742. }
  743.  
  744. //----------------------------------------------------------------------------------------
  745. // CPPictPart::Open
  746. //----------------------------------------------------------------------------------------
  747.  
  748. ODID  CPPictPart::Open(Environment* ev, ODFrame* frame)
  749.  
  750. // Creates and opens a presentation of the part in a frame
  751. // in a new window.
  752. //
  753. // This method adds this part as the root part of the window.
  754. // It bases the presentation in the new frame on the presentation
  755. // in the old frame, or on a default presentation if there
  756. // is no old frame.
  757.  
  758. {
  759.     WeBeHere("\pCPPictPart::Open");
  760.  
  761.     ODWindow*    window = kODNULL;
  762.  
  763.     if (frame)
  764.         window = fSession->GetWindowState(ev)->GetWindow(ev, fWindowID);
  765.  
  766.     if (window == kODNULL)
  767.     {
  768.         window = this->MyMakeWindow(ev, frame);
  769.         fWindowID = window->GetID(ev);
  770.         window->Open(ev);
  771.         window->Show(ev);
  772.     }
  773.  
  774.     window->Select(ev);
  775.  
  776.     return window->GetID(ev);
  777. }
  778.  
  779. //----------------------------------------------------------------------------------------
  780. // CPPictPart::ReleaseAll
  781. //----------------------------------------------------------------------------------------
  782.  
  783. void    CPPictPart::ReleaseAll(Environment* ev)
  784. {
  785.     WeBeHere("\pCPPictPart::ReleaseAll");
  786.  
  787.     if (fMenuBar != kODNULL)
  788.         fMenuBar->Release(ev);
  789. }
  790.  
  791. //----------------------------------------------------------------------------------------
  792. // CPPictPart::MyWantResizable
  793. //----------------------------------------------------------------------------------------
  794.  
  795. ODBoolean CPPictPart::MyWantResizable()
  796. {
  797.     return kODFalse;
  798.         // used in MyMakeWindow() to toggle some parameters
  799. }
  800.  
  801. //----------------------------------------------------------------------------------------
  802. // CPPictPart::MyMakeWindow
  803. //----------------------------------------------------------------------------------------
  804.  
  805. ODWindow*    CPPictPart::MyMakeWindow(Environment* ev, ODFrame* sourceFrame)
  806. {
  807.     WeBeHere("\pCPPictPart::MyMakeWindow");
  808.  
  809.     Rect                windRect;
  810.     ODPlatformWindow    platformWindow = kODNULL;
  811.     ODWindow*            window = kODNULL;
  812.  
  813.     if (sourceFrame)
  814.     {
  815.         SetRect(&windRect, 100, 100, 300, 300);
  816.     }
  817.     else
  818.     {
  819.         const ODSShort        kOnePageWidth = 600;
  820.  
  821.         ::SetRect(&windRect, 4, GetMBarHeight() + 24,
  822.                 ODQDGlobals.screenBits.bounds.right - 64,
  823.                 ODQDGlobals.screenBits.bounds.bottom - 4);
  824.  
  825.         if (windRect.right - windRect.left > kOnePageWidth)
  826.             windRect.right = windRect.left + kOnePageWidth;
  827.     }
  828.  
  829.     Str255        windowTitleStr;
  830.     ODName*    partName = ODGetPOName( ev, fSelf, kODNULL);
  831.     IntlToPStr(partName, (StringPtr)&windowTitleStr);
  832.     DisposeIText(partName);
  833.  
  834.     platformWindow = ::NewCWindow
  835.     (
  836.         kODNULL,
  837.         &windRect,
  838.         windowTitleStr,
  839.         kODFalse,
  840.         this->MyWantResizable() ? zoomDocProc : zoomNoGrow,
  841.         (WindowPtr)-1L,
  842.         kODTrue,
  843.         kODNULL
  844.     );
  845.  
  846.     ODBoolean isRoot = (sourceFrame == kODNULL);
  847.  
  848.     window = fSession->GetWindowState(ev)->RegisterWindow
  849.     (
  850.         ev,
  851.         platformWindow,                                // newWindow
  852.         isRoot ?                                     // Persistent
  853.         kODFrameObject:                             // Non-Persistent
  854.         kODNonPersistentFrameObject,                // frameType
  855.         isRoot,                                        // isRootWindow
  856.         this->MyWantResizable(),                    // isResizable
  857.         kODFalse,                                    // isFloating
  858.         kODTrue,                                    // shouldSave
  859.         fSelf,                                        // rootPart
  860.         fSession->Tokenize(ev, kODViewAsFrame),        // viewType
  861.         fSession->Tokenize(ev, kODPresDefault),        // presentation
  862.         sourceFrame                                    // sourceFrame
  863.     );
  864.  
  865.     return window;
  866. }
  867.  
  868. //----------------------------------------------------------------------------------------
  869. // CPPictPart::Draw
  870. //----------------------------------------------------------------------------------------
  871.  
  872. void CPPictPart::Draw(Environment* ev, ODFacet* facet, ODShape* invalidShape)
  873.  
  874. // Draws the part in the facet, updating the portion of the
  875. // facet in the invalidShape.
  876. //
  877. // Called by the facet object.
  878. //
  879. // The part should draw itself on the facet's canvas. The part
  880. // must examine its canvas' isDynamic flag to determine if it
  881. // will be drawing on the screen or to a printer, and then draw
  882. // itself appropriately.
  883. //
  884. // Draw the part in the given facet. Only the portion in the
  885. // invalidShape needs to be drawn.
  886. //
  887. // There are several steps a part needs to take to perform the
  888. // imaging.
  889. // 1) The part should look at the given facet and its frame.
  890. //    Both the frame and the facet may have some partInfo that
  891. //    the part has placed there, which the part can use to
  892. //    decide how it will display itself.  The frame also has
  893. //    viewType and presentation fields, which indicate what kind
  894. //    of view of the part should display.
  895. // 2) The part should examine its canvas to see how it should
  896. //    be imaged. The canvas can be obtained from the facet via
  897. //    ODFacet::GetCanvas(). If the canvas’ isDynamic flag is
  898. //    kODTrue, the part is imaging onto a dynamic device like
  899. //    a CRT; otherwise, it is imaging to a static device like
  900. //    a printer. The part will probably display its content
  901. //    differently for static and dynamic views. For instance,
  902. //    it should not display scroll bars on a static canvas.
  903. // 3) The part must make sure the platform graphics system is
  904. //    prepared to draw into the correct context for the facet.
  905. //    On the Macintosh using QuickDraw, it is necessary to call
  906. //    SetPort() for the appropriate canvas, and set up other
  907. //    attributes of the drawing environment. A FocusLib library
  908. //    is supplied to help focus drawing commands to a facet.
  909. //    Make sure to clip to the facet’s clipShape (FocusLib
  910. //    does this for you).
  911. // 4) Draw the part’s contents.
  912. // 5) Restore the old graphics environment.
  913. //
  914. // Part editors may sometimes need to display their parts
  915. // asynchronously, that is, not in response to a ::Draw() call.
  916. // This process is very similar to the basic drawing recipe,
  917. // with minor modifications.
  918. // 1) Determine which of the part’s frames should be drawn. A part
  919. //    may have multiple display frames, and more than one may need
  920. //    updating. Parts store their display frames in whatever way
  921. //    they want, so we can’t tell you how to find them here.
  922. // 2) For each frame being displayed, all facets must be drawn.
  923. //    ODFrame::CreateFrameFacetIterator() returns an iterator
  924. //    which will list all the facets of a frame. Draw the part’s
  925. //    contents in each of these facets, using the recipe above.
  926. // 3) After drawing in a facet, call ODFacet::DrawnIn() on it to
  927. //    tell it you’ve drawn in it asynchronously. If the facet is
  928. //    on an offscreen canvas, this lets it get copied into the window.
  929.  
  930. {
  931.     WeBeHere("\pCPPictPart::Draw");
  932.     ODUnused(invalidShape);
  933.  
  934.     CFocus    foc(ev, facet);
  935.  
  936.     ODFrame*    frame     = facet->GetFrame(ev);
  937.     ODShape*    usedShape = frame->GetUsedShape(ev, kODNULL);
  938.     RgnHandle    rgn       = usedShape->GetQDRegion(ev);
  939.  
  940.     usedShape->Release(ev);
  941.  
  942.     Rect        rct     = (*rgn)->rgnBBox;
  943.     RgnHandle    oldClip = NULL;
  944.     RgnHandle    newClip;
  945.  
  946.     ::PenSize(2, 2);
  947.  
  948.     if (frame->IsRoot(ev))
  949.     {
  950.         GrafPtr    curPort;
  951.  
  952.         ::GetPort(&curPort);
  953.         Rect r = curPort->portRect;
  954.         r.left = r.right  - 15;
  955.         r.top  = r.bottom - 15;
  956.         ::GetClip(oldClip = NewRgn());
  957.         ::ClipRect(&r);
  958.         ::DrawGrowIcon(curPort);
  959.         ::GetClip(newClip = ::NewRgn());
  960.         ::DiffRgn(oldClip, newClip, newClip);
  961.         ::SetClip(newClip);
  962.         ::DisposeRgn(newClip);
  963.         ::EraseRect(&(curPort->portRect));
  964.     }
  965.     else {
  966.         ::EraseRoundRect(&rct, 40, 40);
  967.     }
  968.  
  969.     if (frame->GetPresentation(ev) == fPictNormalPresentation )
  970.         {        
  971.         PictPartInfoRec* thisFramePartInfo;
  972.         Boolean temporaryPartInfo = kODFalse;
  973.         
  974.         thisFramePartInfo = (PictPartInfoRec*)frame->GetPartInfo(ev);
  975.         if( thisFramePartInfo == nil )
  976.             {
  977.             temporaryPartInfo = kODTrue;
  978.             thisFramePartInfo = new PictPartInfoRec;
  979.             }
  980.         
  981.         if( fPicture != nil )
  982.             {
  983.             Rect drawRect;
  984.             RgnHandle invalidShapeRgn;
  985.             RgnHandle pictureRgn;
  986.  
  987.             drawRect = CalcPictureRect( ev, thisFramePartInfo );
  988.             // effacement de la région hors picture
  989.             invalidShapeRgn = invalidShape->CopyQDRegion(ev);
  990.             pictureRgn = ::NewRgn();
  991.             ::RectRgn( pictureRgn, &drawRect );
  992.             ::DiffRgn( invalidShapeRgn, pictureRgn, invalidShapeRgn );
  993.             ::DisposeRgn( pictureRgn );
  994.             ::EraseRgn( invalidShapeRgn );
  995.             // dessin
  996.             ::DrawPicture( (PicHandle)fPicture, &drawRect );
  997.             if( frame->GetLinkStatus( ev ) == kODInLinkSource )
  998.                 {
  999.                 Rect tempRect;
  1000.                 tempRect = drawRect;
  1001.                 InsetRect( &tempRect, 1, 1 );
  1002.                 PenPat( &ODQDGlobals.ltGray );
  1003.                 PenSize( 2, 2 );
  1004.                 FrameRect( &tempRect );
  1005.                 PenNormal();
  1006.                 }
  1007.             if( frame->GetLinkStatus( ev ) == kODInLinkDestination )
  1008.                 {
  1009.                 Rect tempRect;
  1010.                 tempRect = drawRect;
  1011.                 InsetRect( &tempRect, 1, 1 );
  1012.                 PenPat( &ODQDGlobals.dkGray );
  1013.                 PenSize( 2, 2 );
  1014.                 FrameRect( &tempRect );
  1015.                 PenNormal();
  1016.                 }
  1017.             }
  1018.         else
  1019.             {
  1020.             RgnHandle frameRgn;
  1021.             
  1022.             frameRgn = frame->GetFrameShape(ev, kODNULL )->CopyQDRegion(ev);
  1023.             ::EraseRgn( frameRgn );
  1024.             if( thisFramePartInfo == nil )
  1025.                 DebugStr("\pthisFramePartInfo == nil in Draw !!!");
  1026.             thisFramePartInfo->Initialize();
  1027.             thisFramePartInfo->activeRect = (*frameRgn)->rgnBBox;
  1028.             ::DisposeRgn( frameRgn );
  1029.             }
  1030.         
  1031.         if( temporaryPartInfo )
  1032.             delete thisFramePartInfo;
  1033.         }
  1034.     else if( frame->GetPresentation(ev) == fPictToolsPresentation )
  1035.         {
  1036.         CUsingLibraryResources fil;
  1037.         PicHandle palettePicture;
  1038.         
  1039.         palettePicture = (PicHandle)::GetResource( 'PICT', 10000 );
  1040.         if( palettePicture != nil )
  1041.             {
  1042.             Rect currentToolRect;
  1043.             Rect paletteDrawRect;
  1044.             
  1045.             paletteDrawRect = (*palettePicture)->picFrame;
  1046.             ::DrawPicture( palettePicture, &paletteDrawRect );
  1047.             ::ReleaseResource( (Handle)palettePicture );
  1048.             
  1049.             ::SetRect( ¤tToolRect, 0, fCurrentTool * toolIconHeight, 
  1050.                                 toolIconWidth, (fCurrentTool + 1) * toolIconHeight );
  1051.             ::InvertRect( ¤tToolRect );
  1052.             
  1053.             if( fPicture == nil )
  1054.                 {
  1055.                 ::SetRect( ¤tToolRect, 0, toolIconHeight, 
  1056.                             toolIconWidth, toolCount * toolIconHeight );
  1057.                 ::PenMode( patBic );
  1058.                 ::PenPat( &ODQDGlobals.gray );
  1059.                 ::PaintRect( ¤tToolRect );
  1060.                 ::PenNormal();
  1061.                 }
  1062.             }
  1063.         }
  1064.  
  1065.     if (oldClip) {
  1066.         ::SetClip(oldClip);
  1067.         ::DisposeRgn(oldClip);
  1068.     }
  1069. }
  1070.  
  1071. //----------------------------------------------------------------------------------------
  1072. // UI Events protocol
  1073. //----------------------------------------------------------------------------------------
  1074.  
  1075. ODBoolean CPPictPart::HandleEvent(Environment* ev, ODEventData* event,
  1076.                                      ODFrame* frame, ODFacet* facet,
  1077.                                      ODEventInfo* eventInfo)
  1078. {
  1079.     WeBeHere("\pCPPictPart::HandleEvent");
  1080. ODUnused(eventInfo);
  1081.  
  1082.     ODBoolean    tWasHandled = kODFalse;
  1083.  
  1084.     switch ( event->what ) {
  1085.         case nullEvent:
  1086.             if (::IsDialogEvent((EventRecord *)event))
  1087.             {
  1088.                 short itemHit;
  1089.                 DialogPtr dialog;
  1090.                 tWasHandled = ::DialogSelect((EventRecord *)event, &dialog, &itemHit);
  1091.                 return tWasHandled;
  1092.             }
  1093.             tWasHandled = kODTrue;
  1094.             break;
  1095.  
  1096.         case mouseDown:
  1097.             tWasHandled = this->MyHandleMouseDown(ev, event, frame, facet);
  1098.             break;
  1099.  
  1100.         case kODEvtMouseDownEmbedded:
  1101.         case mouseUp:
  1102.         case keyDown:
  1103.         case autoKey:
  1104.             tWasHandled = kODTrue;            
  1105.             break;
  1106.         case activateEvt:
  1107.             // PFB
  1108.             if (frame->GetPresentation(ev) == fPictNormalPresentation )
  1109.                 {
  1110.                 PictPartInfoRec* thisFramePartInfo = (PictPartInfoRec *)frame->GetPartInfo(ev);
  1111.                 if( thisFramePartInfo == nil )
  1112.                     DebugStr("\pthisFramePartInfo == nil in activateEvt !!!");
  1113.                 if ((event->modifiers & activeFlag) != 0)
  1114.                     {
  1115.                     if( thisFramePartInfo->fNeedsActivating )
  1116.                         {
  1117.                         if ( fSession->GetArbitrator(ev)->RequestFocusSet(ev, fFocusSet,frame) )
  1118.                             {
  1119.                             this->FocusAcquired(ev, fSelectionFocus, frame);
  1120.                             this->FocusAcquired(ev, fMenuFocus, frame);
  1121.                             this->FocusAcquired(ev, fKeyFocus, frame);
  1122.                             AdjustCursor( ev, thisFramePartInfo );
  1123.                             }
  1124.                         }
  1125.                     }
  1126.                 else
  1127.                     {
  1128.                     if( thisFramePartInfo->fIsActive )
  1129.                         {
  1130.                         fSession->GetArbitrator(ev)->RelinquishFocusSet(ev, fFocusSet, frame);
  1131.                         thisFramePartInfo->fNeedsActivating = true;
  1132.                         }
  1133.                     }
  1134.                 }
  1135.             tWasHandled = kODTrue;            
  1136.             break;
  1137.         case kODEvtMenu:
  1138.             tWasHandled = this->MyHandleMenuEvent(ev, frame, event );
  1139.             break;
  1140.         case kODEvtMouseEnter :
  1141.             // PFB
  1142.             if (facet->GetFrame(ev)->GetPresentation(ev) == fPictNormalPresentation )
  1143.                 {
  1144.                 PictPartInfoRec* thisFramePartInfo = (PictPartInfoRec *)facet->GetFrame(ev)->GetPartInfo(ev);
  1145.                 if( thisFramePartInfo == nil )
  1146.                     DebugStr("\pthisFramePartInfo == nil in MouseEnter !!!");
  1147.                 if( thisFramePartInfo->fIsActive )
  1148.                     {
  1149.                     AdjustCursor( ev, thisFramePartInfo );
  1150.                     }
  1151.                 fMouseInsideActiveFrame = kODTrue;
  1152.                 }
  1153.             break;
  1154.         case kODEvtMouseWithin :
  1155.             // PFB
  1156.             if (facet->GetFrame(ev)->GetPresentation(ev) == fPictNormalPresentation )
  1157.                 {
  1158.                 PictPartInfoRec* thisFramePartInfo = (PictPartInfoRec *)facet->GetFrame(ev)->GetPartInfo(ev);
  1159.                 if( thisFramePartInfo == nil )
  1160.                     DebugStr("\pthisFramePartInfo == nil in MouseWithin !!!");
  1161.                 if( thisFramePartInfo->fIsActive )
  1162.                     {
  1163.                     AdjustCursor( ev, thisFramePartInfo );
  1164.                     }
  1165.                 }
  1166.             break;
  1167.         case kODEvtMouseLeave :
  1168.             // PFB
  1169.             ::SetCursor( &ODQDGlobals.arrow );
  1170.             fMouseInsideActiveFrame = kODFalse;
  1171.             break;
  1172.         default:
  1173.             break;
  1174.     }
  1175.  
  1176.     return tWasHandled;
  1177.  
  1178. // Below is some documentation for this method.  If you don't care for
  1179. // being here, then just delete it.
  1180. //
  1181. // The frame and facet parameters of HandleEvent() may be
  1182. // kODNULL, depending on the kind of event.
  1183. //
  1184. // Parts must handle the following events, which correspond to
  1185. // standard Macintosh events:
  1186. //
  1187. //    kODEvtNull
  1188. //     kODEvtMouseDown
  1189. //     kODEvtMouseUp
  1190. //     kODEvtKeyDown
  1191. //     kODEvtKeyUp
  1192. //     kODEvtAutoKey
  1193. //     kODEvtUpdate
  1194. //     kODEvtActivate
  1195. //     kODEvtOS
  1196. //
  1197. // Null Events --
  1198. // In order to receive null events (i.e. idle time), parts must call
  1199. // ODDispatcher::RegisterIdle(), specifying the part, a frame
  1200. // (optional) and idle frequency. The part will receive a null event
  1201. // for each frame registered. ODDispatcher::GetSleepTime() is called
  1202. // by the shell, and the value passed to WaitNextEvent. An appropriate
  1203. // sleep time is computed based on the idle frequencies of registered
  1204. // idle frames.
  1205. //
  1206. // Mouse Events --
  1207. // Unmodified mouse events are delivered to the facet under the mouse
  1208. // location using Part::HandleEvent().
  1209. //
  1210. // Shift-Click and Command-Click go to the frame with the selection
  1211. // focus.  Mouse events in window title bars are converted to window
  1212. // events. (See below)  Mouse down events in the menu bar are converted
  1213. // to menu events. (See below)
  1214. //
  1215. // Keyboard Events --
  1216. // Keyboard events go to the frame with the keyboard focus, with the
  1217. // exception of the Page Up, Page Down, Home and End keys, which will
  1218. // go to the frame with the scrolling focus, if there is one.
  1219. //
  1220. // Update Events --
  1221. // Update events are not passed to Part::HandleEvent(). Rather
  1222. // Part::Draw() will be called for each facet in the window.
  1223. //
  1224. // Activate Events --
  1225. // Activate events are also delivered to each facet, using
  1226. // Part::HandleEvent().
  1227. //
  1228. // Disk Events --
  1229. // Currently, disk events are not distributed to parts.
  1230. // But where do they go???
  1231. //
  1232. // OS Events --
  1233. // Suspend/Resume events are delivered to each facet in each
  1234. // window using Part::HandleEvent().
  1235. //
  1236. // Mouse Moved events are not passed to Part::HandleEvent().
  1237. // They are handled by the dispatcher, and translated into calls
  1238. // to Part::MouseEnter(), MouseWithin() and MouseLeave().
  1239. // See Cursor Tracking below.
  1240. //
  1241. // Menu Events --
  1242. // OpenDoc converts a mouse down in the menu bar, or its
  1243. // command-key equivalent, into a menu event of type kODEvtMenu.
  1244. //
  1245. // The message field of the event record contains the result
  1246. // returned by MenuSelect() or MenuKey(). i.e. the menu is in
  1247. // the high word, and the item in the low word. The part can
  1248. // obtain a command number using ODMenuBar::GetCommand().
  1249. //
  1250. // Window Events --
  1251. // Events in the title bar of a window (eg. clicking in the
  1252. // close box) are usually handled by the shell, but are first
  1253. // offered to the root part of the window. Parts which wish to
  1254. // intercept these events (perhaps to hide rather than close a
  1255. // window) must handle the following event: kODEvtWindow
  1256. // The message field of the event contains the part code, as
  1257. // returned by FindWindow().
  1258. //
  1259. // Events in Embedded Frames --
  1260. // Parts which support embedding may also receive the following events:
  1261. //
  1262. //    kODEvtMouseDownEmbedded
  1263. //    kODEvtMouseUpEmbedded
  1264. //    kODEvtMouseDownBorder
  1265. //    kODEvtMouseUpBorder
  1266. //
  1267. // If the user clicks in the active border, the containing
  1268. // facet/frame/part will receive a kODEvtMouseDownBorder event.
  1269. // The message field of the event record contains the embedded facet.
  1270. //
  1271. // Similarly, if the user clicks in an embedded frame with the
  1272. // “frozen” or “selected” property set, a kODEvtMouseDownEmbedded
  1273. // event is directed to the containing frame.
  1274. //
  1275. // If the user shift-clicks or command-clicks in a frame which is
  1276. // embedded in the frame with the selection focus, then the latter
  1277. // frame gets a kODEvtMouseDownEmbedded event.
  1278. //
  1279. // Cursor Tracking --
  1280. // OpenDoc tracks cursor movement (with the mouse button up), and
  1281. // calls MouseEnter() when the cursor first moves into a facet, and
  1282. // MouseLeave() when the cursor leaves the facet. A part can change
  1283. // the cursor on MouseEnter, and set it to the arrow on MouseLeave.
  1284. //
  1285. // This process is triggered by the shell calling
  1286. // ODDispatcher::GetMouseRegion() and passing the result to
  1287. // WaitNextEvent(). The region is only recomputed when necessary.
  1288. // If the cursor is motionless within a facet, the shell application
  1289. // goes to sleep because OpenDoc computes a mouse region containing
  1290. // just the cursor location. The part can make this region larger
  1291. // by calling ODDispatcher::SetMouseRegion(). In a future release,
  1292. // OpenDoc will also compute a suitably large sleep region if the
  1293. // cursor is not within any facet.
  1294. //
  1295. // Modal Focus --
  1296. // Some events are constrained by the modal focus. For example a
  1297. // mouse click outside the frame with the modal focus will be sent
  1298. // to the modal focus frame, but a click in an embedded frame
  1299. // within the modal focus frame will go to the embedded frame.
  1300. //
  1301. // Propagating Events --
  1302. // If a containing part sets the “DoesPropagateEvents” property of
  1303. // an embedded frame, the containing part will receive events not
  1304. // handled by the embedded frame. A part which does this will have
  1305. // to inspect the frame passed to HandleEvent() to determine if it
  1306. // is one of its display frames.
  1307.  
  1308. }
  1309.  
  1310. //----------------------------------------------------------------------------------------
  1311.  
  1312. void CPPictPart::AdjustMenus(Environment* ev, ODFrame* frame)
  1313. {
  1314.     WeBeHere("\pCPPictPart::AdjustMenus");
  1315. ODUnused(frame);
  1316.  
  1317.     Str63        aboutText;
  1318.     ODIText*    odiText;
  1319.  
  1320.     fMenuBar->EnableCommand(ev, kODCommandViewAsWin, !frame->IsRoot(ev) );
  1321.     fMenuBar->EnableCommand(ev, kODCommandGetPartInfo, kODTrue);
  1322.  
  1323.     {
  1324.         CUsingLibraryResources fil;
  1325.         ::GetIndString(aboutText,    kContentStringResID, kAboutTextID);
  1326.     }
  1327.  
  1328.     odiText = CreateIText(smRoman, langEnglish, aboutText);
  1329.     fMenuBar->SetItemString(ev, kODCommandAbout, odiText);
  1330.     DisposeIText(odiText);
  1331.  
  1332.     // PFB
  1333.     Str63    showPalette, hidePalette;
  1334.     
  1335.     {
  1336.         CUsingLibraryResources fil;
  1337.         ::GetIndString(showPalette, kContentStringResID, kShowPaletteID);
  1338.         ::GetIndString(hidePalette, kContentStringResID, kHidePaletteID);
  1339.     }
  1340.     if (fPaletteIsOpen)
  1341.         {
  1342.         odiText = CreateIText(smRoman, langEnglish, hidePalette);
  1343.         fMenuBar->SetItemString(ev, kPictPart_PaletteStuff, odiText);
  1344.         DisposeIText(odiText);
  1345.         }
  1346.     else
  1347.         {
  1348.         odiText = CreateIText(smRoman, langEnglish, showPalette);
  1349.         fMenuBar->SetItemString(ev, kPictPart_PaletteStuff, odiText);
  1350.         DisposeIText(odiText);
  1351.         }
  1352.  
  1353.     PictPartInfoRec* framePartInfo = (PictPartInfoRec*)frame->GetPartInfo(ev);
  1354.     fMenuBar->EnableCommand( ev, kPictPart_PaletteStuff, kODTrue );
  1355.     fMenuBar->EnableCommand( ev, kPictPart_ZoomInCmd, (fPicture != nil) && framePartInfo->IsZoomingInAllowed() );
  1356.     fMenuBar->EnableCommand( ev, kPictPart_ZoomOutCmd, (fPicture != nil) && framePartInfo->IsZoomingOutAllowed() );
  1357.     fMenuBar->EnableCommand( ev, kPictPart_ExtOnlyPICT, kODTrue );
  1358.     fMenuBar->CheckCommand( ev, kPictPart_ExtOnlyPICT, fExternalizeOnlyPICTFormat );
  1359.  
  1360.     fMenuBar->EnableCommand( ev, kODCommandCut, (fPicture != nil) );
  1361.     fMenuBar->EnableCommand( ev, kODCommandCopy, (fPicture != nil) );
  1362.     fMenuBar->EnableCommand( ev, kODCommandClear, (fPicture != nil) );
  1363.  
  1364.     ODBoolean okToPaste = kODFalse;
  1365.     ODBoolean okToPasteAs = kODFalse;
  1366.  
  1367.     ODArbitrator* arbitrator = fSession->GetArbitrator(ev);
  1368.     ODTypeToken clipboardFocus = fSession->Tokenize(ev, kODClipboardFocus);
  1369.     
  1370.     if ( (frame == arbitrator->GetFocusOwner(ev, clipboardFocus)) ||
  1371.               (arbitrator->RequestFocus(ev, clipboardFocus, frame)) )
  1372.     {
  1373.         ODClipboard* clipboard = fSession->GetClipboard(ev);
  1374.         // Get the root storage unit for the clipboard
  1375.         ODStorageUnit* clipRootSU = clipboard->GetContentStorageUnit(ev);
  1376.         okToPaste = ValidDataOnSU( ev, clipRootSU );
  1377.         // must be a link in clipboard and not be a link to myself
  1378.         okToPasteAs = ValidLinkOnSU( ev, clipRootSU ) &&
  1379.                         (fClipboardChangeID != clipboard->GetChangeID(ev));
  1380.         arbitrator->RelinquishFocus(ev, clipboardFocus , frame);        
  1381.     }
  1382.  
  1383.     fMenuBar->EnableCommand( ev, kODCommandPaste, okToPaste );
  1384.     fMenuBar->EnableCommand( ev, kODCommandPasteAs, okToPasteAs );
  1385.  
  1386. #define shiftKeyItem    1
  1387. #define shiftKeyMask    1
  1388. #define optionKeyItem    1
  1389. #define optionKeyMask    4
  1390. #define commandKeyItem    1
  1391. #define commandKeyMask    0x8000
  1392. #define controlKeyItem    1
  1393. #define controlKeyMask    8
  1394.     KeyMap theKeyMap;
  1395.     GetKeys( theKeyMap );
  1396.     if( ((fSrcLink != kODNULL) || (fDestLink != kODNULL)) && 
  1397.         (theKeyMap[optionKeyItem] & optionKeyMask))
  1398.         {
  1399.         fShowLinkInfo = kODTrue;
  1400.         fMenuBar->SetItemString(ev, kODCommandGetPartInfo, PStrToIntl("\pLink Info", kODNULL));
  1401.         }
  1402.     else
  1403.         {
  1404.         fShowLinkInfo = kODFalse;
  1405.         fMenuBar->SetItemString(ev, kODCommandGetPartInfo, PStrToIntl("\pPart Info", kODNULL));
  1406.         }
  1407.     
  1408. }
  1409.  
  1410. //----------------------------------------------------------------------------------------
  1411. // CPPictPart::MyHandleMenuEvent
  1412. //----------------------------------------------------------------------------------------
  1413.  
  1414. ODBoolean CPPictPart::MyHandleMenuEvent(Environment* ev, ODFrame* frame, ODEventData* event)
  1415. {
  1416.     WeBeHere("\pCPPictPart::MyHandleMenuEvent");
  1417. ODUnused(frame);
  1418.  
  1419.     long    menuResult = event->message;
  1420.     short    menu = HiWord(menuResult);
  1421.     short    item = LoWord(menuResult);
  1422.  
  1423.     if (menu) {
  1424.  
  1425.         ODCommandID theMenuCommand = fMenuBar->GetCommand(ev, menu, item);
  1426.         switch( theMenuCommand ) {
  1427.  
  1428.             case kODCommandAbout:
  1429.             {
  1430.                 CUsingLibraryResources fil;
  1431.  
  1432.                 if (fSession->GetArbitrator(ev)->RequestFocus(ev, fModalFocus, frame))
  1433.                 {
  1434.                     ::SetCursor(&ODQDGlobals.arrow);
  1435.                     gSession = fSession;                // DialogFilter uses this!
  1436.                     ModalFilterUPP modalFilter = NewModalFilterProc(MyDialogFilter);
  1437.                     ::Alert(kPictPartAboutBoxID, modalFilter);
  1438.                     DisposeRoutineDescriptor(modalFilter);
  1439.                     fSession->GetArbitrator(ev)->RelinquishFocus(ev, fModalFocus,frame);
  1440.                 }
  1441.                 else
  1442.                     ::SysBeep(1);
  1443.             }
  1444.             break;
  1445. /*
  1446.             case kODCommandClear:
  1447.                 break;
  1448. */
  1449.             case kODCommandViewAsWin:
  1450.                 // PFB
  1451.                 if (frame->GetPresentation(ev) == fPictNormalPresentation )
  1452.                     {
  1453.                     PictPartInfoRec* thisFramePartInfo = (PictPartInfoRec *)frame->GetPartInfo(ev);
  1454.                     if( thisFramePartInfo == nil )
  1455.                         DebugStr("\pthisFramePartInfo == nil in activateEvt !!!");
  1456.                     if( thisFramePartInfo->fIsActive )
  1457.                         {
  1458.                         fSession->GetArbitrator(ev)->RelinquishFocusSet(ev, fFocusSet, frame);
  1459.                         thisFramePartInfo->fNeedsActivating = true;
  1460.                         }
  1461.                     }
  1462.                 this->Open(ev, frame);
  1463.                 break;
  1464.  
  1465.             case kODCommandGetPartInfo:
  1466.                 if( fShowLinkInfo )
  1467.                     {
  1468.                     ODLinkInfoResult infoResult;
  1469.                     ODFrameFacetIterator*    facets = frame->CreateFacetIterator(ev);
  1470.                     if( fSrcLink != kODNULL )
  1471.                         {
  1472.                         if ( fSrcLink->ShowLinkSourceInfo( ev, 
  1473.                                         facets->First(ev),
  1474.                                         fSrcLinkChange,
  1475.                                         true,
  1476.                                         &infoResult) )
  1477.                             {
  1478.                             switch( infoResult.action )
  1479.                                 {
  1480.                                 case kODLinkInfoBreakLink:
  1481.                                     RemoveSourceLink(ev);
  1482.                                     break;
  1483.                                 case kODLinkInfoUpdateNow:
  1484.                                     UpdateSourceLink( ev, true );
  1485.                                     break;
  1486.                                 case kODLinkInfoOk :
  1487.                                     if ( infoResult.autoUpdate != fSrcLink->IsAutoUpdate(ev) )
  1488.                                         {
  1489.                                         fSrcLink->SetAutoUpdate(ev, infoResult.autoUpdate);
  1490.                                         if ( infoResult.autoUpdate )
  1491.                                             if ( fSrcLinkChange != fSrcLink->GetChangeID(ev) )
  1492.                                                 {
  1493.                                                 // Changed from manual to automatic updates, and the link
  1494.                                                 // is out of date; update it now
  1495.                                                 UpdateSourceLink( ev, true );
  1496.                                                 }
  1497.                                         }
  1498.                                     break;
  1499.                                 }
  1500.                             }
  1501.                         }
  1502.                     else if( fDestLink != kODNULL )
  1503.                         {
  1504.                         if ( fDestLink->ShowLinkDestinationInfo(ev, 
  1505.                                                         facets->First(ev),
  1506.                                                         &fDestLinkInfo, 
  1507.                                                         true,
  1508.                                                         &infoResult) )
  1509.                             {
  1510.                             switch (infoResult.action)
  1511.                                  {
  1512.                                 case kODLinkInfoFindSource:
  1513.                                     TRY
  1514.                                         fDestLink->ShowSourceContent(ev);
  1515.                                     CATCH_ALL
  1516.                                         SysBeep( 30 );
  1517.                                         SysBeep( 30 );
  1518.                                         SysBeep( 30 );
  1519.                                         // DebugStr("\pPictPart : Error returned by ODLink::ShowSourceContent" );
  1520.                                     ENDTRY;
  1521.                                     break;
  1522.                                 case kODLinkInfoBreakLink:
  1523.                                     RemoveDestLink(ev);
  1524.                                     break;
  1525.                                 case kODLinkInfoUpdateNow:
  1526.                                     LinkUpdated(ev, fDestLink, fDestLink->GetChangeID(ev));
  1527.                                     break;
  1528.                                 case kODLinkInfoOk:
  1529.                                     if ( infoResult.autoUpdate != fDestLinkInfo.autoUpdate )
  1530.                                         {
  1531.                                         fDestLinkInfo.autoUpdate = infoResult.autoUpdate;
  1532.                                         if( infoResult.autoUpdate )
  1533.                                             fDestLink->RegisterDependent( ev, fSelf, fDestLinkInfo.change );
  1534.                                         else
  1535.                                             fDestLink->UnregisterDependent( ev, fSelf );
  1536.                                         }
  1537.                                     break;
  1538.                                 default:
  1539.                                     break;
  1540.                                 }
  1541.                             }
  1542.                         }
  1543.                     delete facets;
  1544.                     }
  1545.                 else
  1546.                     {
  1547.                     ODFrameFacetIterator* facets = frame->CreateFacetIterator(ev);
  1548.                     fSession->GetInfo(ev)->ShowPartFrameInfo(ev, facets->First(ev), true ); //Adkins
  1549.                     delete facets;
  1550.                     }
  1551.                 break;
  1552.  
  1553.             // PFB
  1554.             case kODCommandCut :
  1555.             case kODCommandCopy :
  1556.                 {
  1557.                 ODArbitrator* arbitrator = fSession->GetArbitrator(ev);
  1558.                 ODTypeToken clipboardFocus = fSession->Tokenize(ev, kODClipboardFocus);
  1559.                 
  1560.                 if ( (frame == arbitrator->GetFocusOwner(ev, clipboardFocus)) ||
  1561.                           (arbitrator->RequestFocus(ev, clipboardFocus, frame)) )
  1562.                     {
  1563.                     ODClipboard* clipboard = fSession->GetClipboard(ev);
  1564.                     // Remove any existing data on the clipboard
  1565.                     clipboard->Clear(ev);
  1566.                     // Get the root storage unit for the clipboard
  1567.                     ODStorageUnit* clipRootSU = clipboard->GetContentStorageUnit(ev);
  1568.                     // Part specific code to write to the clipboard draft via 'clipRootSU'.
  1569.                     PrepareSU( ev, clipRootSU );
  1570.                     ExternalizeToSU( ev, clipRootSU, frame );
  1571.                     if( theMenuCommand == kODCommandCopy )
  1572.                         ExternalizeLinkToSU( ev, clipRootSU );
  1573.                     arbitrator->RelinquishFocus(ev, clipboardFocus , frame);
  1574.                     // memorize the change ID to detect cut/püaste in myself
  1575.                     fClipboardChangeID = clipboard->GetChangeID(ev);
  1576.                     }
  1577.                 if( theMenuCommand == kODCommandCut )
  1578.                     {
  1579.                     DisposeHandle( fPicture );
  1580.                     fPicture = nil;
  1581.                     fCurrentTool = arrowTool;
  1582.                     MyInvalAllDisplayFrames(ev);
  1583.                     MySetDirty(ev);
  1584.                     }
  1585.  
  1586.                 break;
  1587.                 }
  1588.  
  1589.             case kODCommandPasteAs :
  1590.                 {
  1591.                 ODArbitrator* arbitrator = fSession->GetArbitrator(ev);
  1592.                 ODTypeToken clipboardFocus = fSession->Tokenize(ev, kODClipboardFocus);
  1593.                 
  1594.                 if( (frame == arbitrator->GetFocusOwner(ev, clipboardFocus)) || (arbitrator->RequestFocus(ev, clipboardFocus, frame)) )
  1595.                     {
  1596.                     ODClipboard* clipboard = fSession->GetClipboard(ev);
  1597.                     ODFrameFacetIterator* facets = (ODFrameFacetIterator*) kODNULL;
  1598.                     ODPasteAsResult pasteAsRslt;
  1599.                     
  1600.                     pasteAsRslt.pasteLinkSetting = kODTrue;
  1601.                     TRY
  1602.                         {
  1603.                         ODStorageUnit* clipContentSU = clipboard->GetContentStorageUnit(ev);
  1604.                         facets = frame->CreateFacetIterator(ev);
  1605.                         if ( clipboard->ShowPasteAsDialog(ev, 
  1606.                                     kODTrue,
  1607.                                     kODFalse,
  1608.                                     facets->First(ev),
  1609.                                     fSession->Tokenize(ev, kODViewAsFrame),
  1610.                                     &pasteAsRslt) )
  1611.                             {
  1612.                             // Cannot paste a link if translation is required
  1613.                             if ( pasteAsRslt.translateKind != kODNULL )
  1614.                                 DebugStr("\pcannot translate !!!");
  1615.                             if( fPicture != nil )
  1616.                                 {
  1617.                                 ::DisposeHandle( fPicture );
  1618.                                 fPicture = nil;
  1619.                                 fCurrentTool = arrowTool;
  1620.                                 }
  1621.                             // Get the root storage unit for the clipboard
  1622.                             ODStorageUnit* clipRootSU = clipboard->GetContentStorageUnit(ev);
  1623.                             InternalizeFromSU(ev, clipRootSU );
  1624.                             InternalizeLinkFromSU(ev, clipRootSU, &pasteAsRslt );
  1625.                             arbitrator->RelinquishFocus(ev, clipboardFocus , frame);        
  1626.                             }
  1627.                         }
  1628.                     CATCH_ALL
  1629.                         somPrintf("DoPasteAs caught error %d\n", ErrorCode());
  1630.                     ENDTRY
  1631.                     delete facets;
  1632.                     if( pasteAsRslt.pasteLinkSetting == kODTrue )
  1633.                         break;
  1634.                     }
  1635.                 // NO break; continue if simple paste !!!
  1636.                 }
  1637.                 
  1638.             case kODCommandPaste :
  1639.                 {
  1640.                 ODArbitrator* arbitrator = fSession->GetArbitrator(ev);
  1641.                 ODTypeToken clipboardFocus = fSession->Tokenize(ev, kODClipboardFocus);
  1642.                 
  1643.                 if ( (frame == arbitrator->GetFocusOwner(ev, clipboardFocus)) ||
  1644.                           (arbitrator->RequestFocus(ev, clipboardFocus, frame)) )
  1645.                     {
  1646.                     ODClipboard* clipboard = fSession->GetClipboard(ev);
  1647.                     // Get the root storage unit for the clipboard
  1648.                     ODStorageUnit* clipRootSU = clipboard->GetContentStorageUnit(ev);
  1649.                     Boolean gotSomething = InternalizeFromSU( ev, clipRootSU, frame );
  1650.                     if( gotSomething )
  1651.                         RemoveDestLink( ev );
  1652.                     arbitrator->RelinquishFocus(ev, clipboardFocus , frame);        
  1653.                     }
  1654.                 break;
  1655.                 }
  1656.  
  1657.             case kODCommandClear :
  1658.                 {
  1659.                 if( fPicture != nil )
  1660.                     {
  1661.                     ::DisposeHandle( fPicture );
  1662.                     fPicture = nil;
  1663.                     fCurrentTool = arrowTool;
  1664.                     }
  1665.                 MyInvalAllDisplayFrames(ev);
  1666.                 MySetDirty(ev);
  1667.                 break;
  1668.                 }
  1669.  
  1670.             case kPictPart_ZoomInCmd :
  1671.                 {
  1672.                 PictPartInfoRec* framePartInfo;            
  1673.                 framePartInfo = (PictPartInfoRec*)frame->GetPartInfo(ev);
  1674.                 framePartInfo->ZoomIn();
  1675.                 frame->Invalidate(ev, kODNULL, kODNULL);
  1676.                 MySetDirty(ev);
  1677.                 break;
  1678.                 }
  1679.             case kPictPart_ZoomOutCmd :
  1680.                 {
  1681.                 PictPartInfoRec* framePartInfo;            
  1682.                 framePartInfo = (PictPartInfoRec*)frame->GetPartInfo(ev);
  1683.                 framePartInfo->ZoomOut();
  1684.                 frame->Invalidate(ev, kODNULL, kODNULL);
  1685.                 MySetDirty(ev);
  1686.                 break;
  1687.                 }
  1688.             case kPictPart_ExtOnlyPICT :
  1689.                 {
  1690.                 fExternalizeOnlyPICTFormat = !fExternalizeOnlyPICTFormat;
  1691.                 break;
  1692.                 }
  1693.  
  1694.             case kPictPart_PaletteStuff :
  1695.                 {
  1696.                 if( fPaletteIsOpen == kODFalse )
  1697.                     {
  1698.                     if( fPaletteWindow == nil )
  1699.                         {
  1700.                         ODPlatformWindow    platformWindow;
  1701.                         Rect                windRect;
  1702.                         
  1703.                         ::SetRect(&windRect, 0, 0, toolIconWidth, toolIconHeight * toolCount );
  1704.                         platformWindow = ::NewCWindow( kODNULL, &windRect,"\p",
  1705.                                         kODFalse, noGrowDocProc, (WindowPtr)-1L, kODTrue, kODNULL );
  1706.                         ::MoveWindow( platformWindow, 100, 100, kODFalse);
  1707.                         fPaletteWindow = fSession->GetWindowState(ev)->RegisterWindow(    
  1708.                                                     ev,
  1709.                                                     platformWindow, // newWindow
  1710.                                                     kODNonPersistentFrameObject,
  1711.                                                     kODFalse,        // isRootWindow
  1712.                                                     kODFalse,        // Is resizable
  1713.                                                     kODTrue,        // Is floating
  1714.                                                     kODFalse,        // don't save
  1715.                                                     fSelf, 
  1716.                                                     fSession->Tokenize(ev,kODViewAsFrame),
  1717.                                                     fPictToolsPresentation,
  1718.                                                     kODNULL);
  1719.                         fPaletteWindow->Open(ev);
  1720.                         }
  1721.                     fPaletteWindow->Show(ev);
  1722.                     fPaletteIsOpen = kODTrue;
  1723.                     }
  1724.                 else
  1725.                     {
  1726.                     fPaletteWindow->Hide(ev);
  1727.                     fCurrentTool = arrowTool;
  1728.                     fPaletteIsOpen = kODFalse;
  1729.                     }
  1730.                 break;
  1731.                 }
  1732. /*
  1733.  
  1734.             case kODPictPart_LoadFile :
  1735.                 {
  1736.                 OSErr err;
  1737.                 SFTypeList typeList;
  1738.                 StandardFileReply reply;
  1739.     
  1740.                 typeList[0] = 'PICT';
  1741.                 StandardGetFilePreview( (FileFilterProcPtr)nil, 1, typeList, &reply);
  1742.                 if (reply.sfGood == kODTrue)
  1743.                     {
  1744.                     short fileRefNum;
  1745.                     long fileSize;
  1746.                     
  1747.                     err = FSpOpenDF( &reply.sfFile, fsRdPerm, &fileRefNum );
  1748.                     if( err != noErr )
  1749.                         DebugStr("\pcannot FSpOpenDF !!!");
  1750.                     err = GetEOF( fileRefNum, &fileSize );
  1751.                     if( err != noErr )
  1752.                         DebugStr("\pcannot GetEOF !!!");
  1753.                     err = SetFPos( fileRefNum, fsFromStart, 512 );
  1754.                     if( err != noErr )
  1755.                         DebugStr("\pcannot SetFPos !!!");
  1756.                     fileSize -= 512;
  1757.                     if( fPicture != nil )
  1758.                         {
  1759.                         DisposeHandle( fPicture );
  1760.                         fPicture = nil;
  1761.                         }
  1762.                     fPicture = NewHandle( fileSize );
  1763.                     if( fPicture == nil )
  1764.                         {
  1765.                         FSClose( fileRefNum );
  1766.                         SysBeep( 30 );
  1767.                         }
  1768.                     HLock( fPicture );
  1769.                     err = FSRead( fileRefNum, &fileSize, *fPicture );
  1770.                     if( err != noErr )
  1771.                         DebugStr("\pcannot FSRead !!!");
  1772.                     HUnlock( fPicture );
  1773.                     FSClose( fileRefNum );
  1774.                     }
  1775.                 frame->Invalidate(ev, kODNULL, kODNULL);
  1776.                 MySetDirty();
  1777.                 break;
  1778.                 }
  1779. */
  1780.             default:
  1781.                 return kODFalse;
  1782.         }
  1783.     }
  1784.  
  1785.     return kODTrue;
  1786. }
  1787.  
  1788.  
  1789.  
  1790. //------------------------------------------------------------------------------
  1791. // CPPictPart::MyHandleMouseDown
  1792. //------------------------------------------------------------------------------
  1793.  
  1794. ODBoolean CPPictPart::MyHandleMouseDown(Environment* ev, ODEventData* event,
  1795.                                          ODFrame* frame, ODFacet* facet)
  1796. {
  1797.     WeBeHere("\pCPPictPart::MyHandleMouseDown");
  1798.  
  1799.     ODBoolean handled = kODFalse;
  1800.  
  1801.     if (facet == kODNULL)        // Did we get a click outside a modal dialog? …
  1802.     {
  1803.         ::SysBeep(1);
  1804.         return kODTrue;            // Return that click was handled.
  1805.     }
  1806.  
  1807.     // Activate the window if it is not active…
  1808.     if (! facet->GetWindow(ev)->IsActive(ev))
  1809.     {
  1810.         facet->GetWindow(ev)->Select(ev);
  1811.  
  1812. #ifdef FIRST_CLICK_WINDOW_BEHAVIOR
  1813.         handled = kODTrue;
  1814. #else
  1815.         return kODTrue;
  1816. #endif
  1817.         // We argued way too much about which this should be.  The answer is that
  1818.         // some types of content need first click, and some absolutely don't.  Even
  1819.         // for 'TEXT', sometimes you want one, and sometimes you want the other.
  1820.         // It depends on your content, usage model, etc.
  1821.         //
  1822.         // If you are unsure about which you want, the default for PictPart
  1823.         // should be FIRST_CLICK_WINDOW_BEHAVIOR.  This probably means fewer clicks
  1824.         // for the user.  If this doesn't work for your part, of course change it.
  1825.     }
  1826.  
  1827.     if (::IsDialogEvent((EventRecord *)event))
  1828.     {
  1829.         short        itemHit;
  1830.         DialogPtr    dialog;
  1831.  
  1832.         handled = ::DialogSelect((EventRecord *)event, &dialog, &itemHit);
  1833.         ODWindow* window = fSession->GetWindowState(ev)->GetODWindow(ev, dialog);
  1834.         return handled;        // In preparation for more "if" cases to be added below.
  1835.     }
  1836.  
  1837.     // get the mouse in local coordinates
  1838.     ODWindow* odwnd = frame->GetWindow(ev);
  1839.     ODPoint odPoint;
  1840.     GetWindowPoint(odwnd, ev, event->where, &odPoint);
  1841.  
  1842.     // test for click in grow box, if appropriate
  1843.     if (frame->IsRoot(ev))
  1844.     {
  1845.         WindowPtr wnd   = (WindowPtr)odwnd->GetPlatformWindow(ev);
  1846.  
  1847.         Rect r = wnd->portRect;
  1848.         r.left = r.right  - 15;
  1849.         r.top  = r.bottom - 15;
  1850.         if (::PtInRect(odPoint.AsQDPoint(), &r)) {
  1851.             ::SetRect(&r, 200, 200, 20000, 20000);
  1852.             long newWindowSize = GrowWindow(wnd, event->where, &r);
  1853.             ::SizeWindow(wnd, LoWord(newWindowSize), HiWord(newWindowSize), kODTrue);
  1854.             odwnd->AdjustWindowShape(ev);
  1855.             return kODTrue;
  1856.         }
  1857.     }
  1858.  
  1859.     // PFB
  1860.     if( frame->GetPresentation(ev) == fPictToolsPresentation )
  1861.         {
  1862.         if( fPicture != nil )
  1863.             {
  1864.             CFocus foc(ev, facet);
  1865.             PictPartInfoRec* thisFramePartInfo;
  1866.             Point where = event->where;
  1867.     
  1868.             thisFramePartInfo = (PictPartInfoRec*)frame->GetPartInfo(ev);
  1869.             ::GlobalToLocal(&where);                    
  1870.             fCurrentTool = (PictPartTool)(where.v / toolIconHeight);
  1871.             facet->Invalidate( ev, kODNULL, kODNULL );
  1872.             return kODTrue;
  1873.             }
  1874.         }
  1875.     else if( frame->GetPresentation(ev) == fPictNormalPresentation )
  1876.         {
  1877.         PictPartInfoRec* thisFramePartInfo = (PictPartInfoRec *)frame->GetPartInfo(ev);
  1878.         if( thisFramePartInfo == nil )
  1879.             DebugStr("\pthisFramePartInfo == nil in MyHandleMouseDown !!!");
  1880.         if( thisFramePartInfo->fIsActive == kODFalse )
  1881.             {
  1882.             // Try to grab all of our foci…
  1883.             if ( fSession->GetArbitrator(ev)->RequestFocusSet(ev, fFocusSet,frame) )
  1884.                 {
  1885.                 this->FocusAcquired(ev, fSelectionFocus, frame);
  1886.                 this->FocusAcquired(ev, fMenuFocus, frame);
  1887.                 this->FocusAcquired(ev, fKeyFocus, frame);
  1888.                 AdjustCursor( ev, thisFramePartInfo );
  1889.                 return kODTrue;
  1890.     
  1891.                 } 
  1892.             else
  1893.                 return kODFalse;    // We couldn't get focus.
  1894.     
  1895.             // Of course, you shouldn't fail if you really don't need the *all*
  1896.             // of the foci.  For example, a vector drawing part that also has
  1897.             // a text tool should probably go ahead and allow drawing while
  1898.             // disabling the text tool.
  1899.             }
  1900.  
  1901.     
  1902.         // Handle clicks in used shape…
  1903.         odPoint = facet->GetWindowContentTransform(ev, kODNULL)->InvertPoint(ev, &odPoint);
  1904.     
  1905.         ODShape*  usedShape = this->MyGetUsedShape(ev, frame);
  1906.         ODBoolean hit       = usedShape->ContainsPoint(ev, &odPoint);
  1907.         usedShape->Release(ev);
  1908.     
  1909.         if (hit)
  1910.             return this->MyUsedShapeHandleMouseDown(ev, event, frame, facet);
  1911.         }
  1912.  
  1913.     return handled;
  1914. }
  1915.  
  1916.  
  1917.  
  1918. //------------------------------------------------------------------------------
  1919. // CPPictPart::MyUsedShapeHandleMouseDown
  1920. //------------------------------------------------------------------------------
  1921.  
  1922. ODBoolean CPPictPart::MyUsedShapeHandleMouseDown(Environment* ev, ODEventData* event,
  1923.                                          ODFrame* frame, ODFacet* facet)
  1924. {
  1925.     WeBeHere("\pCPPictPart::MyUsedShapeHandleMouseDown");
  1926.  
  1927.     // Get the window and platform window (i.e. WindowPtr)…
  1928.     ODWindow* odwnd = frame->GetWindow(ev);
  1929.     ODPlatformWindow facetPort = odwnd->GetPlatformWindow(ev);
  1930.  
  1931.     // Get the mouse in window-local and facet-local coordinates…
  1932.     ODPoint windowPoint;
  1933.     GetWindowPoint(odwnd, ev, event->where, &windowPoint);
  1934.     ODPoint facetPoint = facet->GetWindowContentTransform(ev, kODNULL)->
  1935.                             InvertPoint(ev, &windowPoint);
  1936.  
  1937.     // Handle the click in whatever way is appropriate…
  1938.     {
  1939.         
  1940.         Point        macPoint;
  1941.         {
  1942.         CFocus foc(ev, facet);
  1943.         macPoint = facetPoint.AsQDPoint();
  1944.         }
  1945.     
  1946.         // PFB
  1947.         PictPartInfoRec* thisFramePartInfo;
  1948.         thisFramePartInfo = (PictPartInfoRec*)frame->GetPartInfo(ev);
  1949.             if( thisFramePartInfo == nil )
  1950.                 DebugStr("\pthisFramePartInfo == nil in MyUsedShapeHandleMouseDown !!!");
  1951.  
  1952.         switch( fCurrentTool )
  1953.             {
  1954.             case arrowTool :
  1955.                 if( WaitMouseMoved(event->where) && 
  1956.                     ::PtInRect( macPoint, &thisFramePartInfo->activeRect ) &&
  1957.                     (fPicture != nil) )
  1958.                     {
  1959.                     // Get the ODDragAndDrop object from the session.
  1960.                     ODDragAndDrop* dragAndDrop;
  1961.                     
  1962.                     dragAndDrop = fSession->GetDragAndDrop(ev);
  1963.                     dragAndDrop->Clear(ev);
  1964.                     ODStorageUnit* storageUnit = dragAndDrop->GetContentStorageUnit(ev);
  1965.                     PrepareSU( ev, storageUnit );
  1966.                     ExternalizeToSU( ev, storageUnit, frame );
  1967.                     ExternalizeLinkToSU( ev, storageUnit );
  1968.  
  1969.                     ODDropResult dropResult;
  1970.                     ODByteArray eventBA;
  1971.                     ODByteArray dragRgnBA;
  1972.                     ODPart *destPart;
  1973.                     // Initiate the Dragging
  1974.                     RgnHandle dragRgn;
  1975.                     Rect tempRect;
  1976.                     Point xForm;
  1977.  
  1978.                     {
  1979.                     CFocus foc(ev, facet);
  1980.                     dragRgn = ::NewRgn();
  1981.                     ::OpenRgn();
  1982.                     tempRect = thisFramePartInfo->activeRect;
  1983.                     ::FrameRect( &tempRect );
  1984.                     ::InsetRect( &tempRect, 2, 2 );
  1985.                     ::FrameRect( &tempRect );                    
  1986.                     ::CloseRgn( dragRgn );
  1987.  
  1988.                     SetPt(&xForm, 0, 0);
  1989.                     LocalToGlobal(&xForm);
  1990.                     OffsetRgn(dragRgn, xForm.h, xForm.v);
  1991.                     }
  1992.  
  1993.                     eventBA = CreateByteArrayStruct(&event, sizeof(ODEventData*));
  1994.                     dragRgnBA = CreateByteArrayStruct(&dragRgn, sizeof(RgnHandle));
  1995.                     dropResult = dragAndDrop->StartDrag( ev, facet->GetFrame(ev), 
  1996.                                     kODDragImageRegionHandle, &dragRgnBA, &destPart, &eventBA );
  1997.  
  1998.                     DisposeByteArrayStruct(dragRgnBA);
  1999.                     DisposeByteArrayStruct(eventBA);
  2000.  
  2001.                     if( dropResult == kODDropMove )
  2002.                         {
  2003.                         ::DisposeHandle( fPicture );
  2004.                         fPicture = nil;
  2005.                         fCurrentTool = arrowTool;
  2006.                         }
  2007.                     ::DisposeRgn( dragRgn );
  2008.                     }
  2009.                 break;
  2010.  
  2011.             case moveTool :
  2012.                 {
  2013.                 Point theLoc = {0,0};
  2014.                 Point lastLoc = {0,0};
  2015.                 ODBoolean mustRedraw = kODFalse;
  2016.                 Point *pictureOffsetPtr;
  2017.             
  2018.                 pictureOffsetPtr = &thisFramePartInfo->pictureOffset;
  2019.                 
  2020.                 ::GetMouse(&lastLoc);
  2021.                 while( ::StillDown() )
  2022.                     {
  2023.                     ::GetMouse(&theLoc);
  2024.                     if ((theLoc.h != lastLoc.h) || (theLoc.v != lastLoc.v))
  2025.                         {
  2026.                         Point offsetDelta;
  2027.                         
  2028.                         offsetDelta = theLoc;
  2029.                         ::SubPt( lastLoc, &offsetDelta );
  2030.                         ::AddPt( offsetDelta, pictureOffsetPtr );
  2031.                         lastLoc = theLoc;
  2032.                         mustRedraw = kODTrue;
  2033.                         }
  2034.                     else if( mustRedraw )
  2035.                         {
  2036.                         Draw( ev, facet, frame->GetUsedShape(ev, kODNULL) );
  2037.                         mustRedraw = kODFalse;
  2038.                         }
  2039.                     }
  2040.                 break;
  2041.                 }
  2042.             case zoomInTool :
  2043.                 if( thisFramePartInfo->IsZoomingInAllowed() )
  2044.                     {
  2045.                     thisFramePartInfo->ZoomIn();
  2046.                     frame->Invalidate(ev, kODNULL, kODNULL);
  2047.                     MySetDirty(ev);
  2048.                     if( fMouseInsideActiveFrame )
  2049.                         AdjustCursor( ev, thisFramePartInfo );
  2050.                     }
  2051.                 break;
  2052.             case zoomOutTool :
  2053.                 if( thisFramePartInfo->IsZoomingOutAllowed() )
  2054.                     {
  2055.                     thisFramePartInfo->ZoomOut();
  2056.                     frame->Invalidate(ev, kODNULL, kODNULL);
  2057.                     MySetDirty(ev);
  2058.                     if( fMouseInsideActiveFrame )
  2059.                         AdjustCursor( ev, thisFramePartInfo );
  2060.                     }
  2061.                 break;
  2062.             }
  2063.         }
  2064.  
  2065.     return kODTrue;        // We handled the click.
  2066. }
  2067.  
  2068. //----------------------------------------------------------------------------------------
  2069. // Facet protocol
  2070. //----------------------------------------------------------------------------------------
  2071.  
  2072. void CPPictPart::FacetAdded(Environment* ev, ODFacet* facet)
  2073. {
  2074.     WeBeHere("\pCPPictPart::FacetAdded");
  2075.  
  2076.     ODFrame* frame = facet->GetFrame(ev);
  2077.     frame->RequestFrameShape(ev, this->MyGetFrameShape(ev, frame), kODNULL);
  2078.         // •• First, MyGetFrameShape is called to calculate the frame
  2079.         // shape we want.  However, we might not get it, due to the
  2080.         // needs/constraints of the containing part.  Therefore, after
  2081.         // calculating what we want, we see if we can get it by calling
  2082.         // RequestFrameShape.
  2083.         // RequestFrameShape either returns us what we passed it, or
  2084.         // returns something else because it thinks it knows best.
  2085.         // Either way, we then proceed with the returned result.
  2086.         // Note that this means that we have to be prepared to deal
  2087.         // with a frame shape other than we desire.
  2088.  
  2089.     this->MyAdjustFacets(ev, frame);
  2090.         // Given a new negotiated frame shape, adjust our facets based
  2091.         // on it.  That's all there is to it.
  2092.  
  2093.     // PFB
  2094.     if (frame->IsRoot(ev) && (frame->GetPresentation(ev) == fPictNormalPresentation))
  2095.     {
  2096.         ODBoolean succeeded = kODFalse;
  2097.         succeeded = fSession->GetArbitrator(ev)->RequestFocusSet(ev, fFocusSet,frame);
  2098.         if (succeeded)
  2099.         {
  2100.             this->FocusAcquired(ev, fSelectionFocus, frame);
  2101.             this->FocusAcquired(ev, fMenuFocus, frame);
  2102.             this->FocusAcquired(ev, fKeyFocus, frame);
  2103.         }
  2104.     }
  2105. }
  2106.  
  2107. //----------------------------------------------------------------------------------------
  2108. // CPPictPart::MyInvalAllDisplayFrames
  2109. //----------------------------------------------------------------------------------------
  2110.  
  2111. void CPPictPart::MyInvalAllDisplayFrames(Environment* ev)
  2112. {
  2113.     WeBeHere("\pCPPictPart::MyInvalAllDisplayFrames");
  2114.  
  2115.     // This is just a CPPictPart utility method.
  2116.  
  2117.     for (FrameLink *fl = fDisplayFrames.First(); fl->Frame(); fl = fl->Next())
  2118.         fl->Frame()->Invalidate(ev, kODNULL, kODNULL);
  2119. }
  2120.  
  2121. //----------------------------------------------------------------------------------------
  2122. // Part Activation protocol
  2123. //----------------------------------------------------------------------------------------
  2124.  
  2125. ODBoolean CPPictPart::BeginRelinquishFocus(Environment* ev, ODTypeToken focus,
  2126.                                               ODFrame* ownerFrame,
  2127.                                               ODFrame* proposedFrame)
  2128. {
  2129.     WeBeHere("\pCPPictPart::BeginRelinquishFocus");
  2130. ODUnused(ownerFrame);
  2131.  
  2132.     if ((focus == fModalFocus) && (proposedFrame->GetPart(ev) != fSelf)) {
  2133.         return kODFalse;
  2134.             // •• 6/23/94
  2135.             // What IS ModalFocus, anyway?  The whole purpose of this
  2136.             // ModalFocus thing is to restrict frame changes.  This is
  2137.             // the part's chance to do this.  But how much to restrict…
  2138.             //
  2139.             // This is an interesting case.  ModalFocus is kind of a weird
  2140.             // concept in OpenDoc, as it goes against the principal of
  2141.             // being able to click anywhere at any time.  This implementation
  2142.             // keeps the focus on the part.  Note that the implementation
  2143.             // of ModalFocus might be more restrictive than this.  You may
  2144.             // wish to restrict it to a single frame, instead of allowing
  2145.             // the focus to move from frame to frame within a single part.
  2146.             // If you wish to restrict it to a single frame, then the if
  2147.             // should only check if it is a modal focus.
  2148.     }
  2149.     else {
  2150.         return kODTrue;
  2151.             // This is the super-script way of handling ModalFocus.  You
  2152.             // can NOT switch off the frame to another, no matter what.
  2153.     }
  2154. }
  2155.  
  2156. //----------------------------------------------------------------------------------------
  2157.  
  2158. void CPPictPart::CommitRelinquishFocus(Environment* ev,
  2159.                                         ODTypeToken focus, ODFrame* ownerFrame,
  2160.                                         ODFrame* proposedFrame)
  2161. {
  2162.     WeBeHere("\pCPPictPart::CommitRelinquishFocus");
  2163. ODUnused(proposedFrame);
  2164.  
  2165.     this->FocusLost(ev, focus, ownerFrame);
  2166.         // •• 6/23/94
  2167.         // No choices to be made here.  It's too late to say no.  We are
  2168.         // losing the focus if we are here.  Getting called here means
  2169.         // that BeginRelinquishFocus has already agreed that losing focus
  2170.         // is okay.  If you don't want this to be happening, then you need
  2171.         // to do something in BeginRelinquishFocus.
  2172.         //
  2173.         // The way that some other samples are currently written I believe
  2174.         // to be in error.  The recipes say that when this is called, it
  2175.         // has already been decided that, focus-wise, you lose.  Therefore
  2176.         // there should be no conditions on calling FocusLost.
  2177. }
  2178.  
  2179. //----------------------------------------------------------------------------------------
  2180.  
  2181. void CPPictPart::AbortRelinquishFocus(Environment* ev,
  2182.                                        ODTypeToken focus, ODFrame* ownerFrame,
  2183.                                        ODFrame* proposedFrame)
  2184. {
  2185.     WeBeHere("\pCPPictPart::AbortRelinquishFocus");
  2186. ODUnused(focus);
  2187. ODUnused(ownerFrame);
  2188. ODUnused(proposedFrame);
  2189.  
  2190.     // •• 6/23/94
  2191.     // Being here means that BeginRelinquishFocus said no to one of the foci.
  2192.     // You are being informed of this because you may have already taken action
  2193.     // based on a previous focus.  Note that if foci are managed as a set, if
  2194.     // BeginRelinquishFocus says kODFalse to any of the foci, then no action is
  2195.     // taken.  If however the foci are tested one at a time, it is possible that
  2196.     // the part has already taken action based on the first foci, and therefore
  2197.     // needs to undo something once a foci says no thanks.
  2198. }
  2199.  
  2200. //----------------------------------------------------------------------------------------
  2201.  
  2202. void CPPictPart::FocusAcquired(Environment* ev, ODTypeToken focus, ODFrame* ownerFrame)
  2203. {
  2204.     WeBeHere("\pCPPictPart::FocusAcquired");
  2205.     // PFB
  2206.     if (focus == fSelectionFocus) 
  2207.         {
  2208.         PictPartInfoRec* thisFramePartInfo = (PictPartInfoRec *)ownerFrame->GetPartInfo(ev);
  2209.             if( thisFramePartInfo == nil )
  2210.                 DebugStr("\pthisFramePartInfo == nil in FocusAcquired !!!");
  2211.         thisFramePartInfo->fIsActive = kODTrue;
  2212.     
  2213.         if( fPaletteIsOpen )
  2214.             fPaletteWindow->Show(ev);
  2215.         }
  2216.  
  2217.     if (focus == fMenuFocus)
  2218.         if (ownerFrame && fMenuBar)
  2219.         {
  2220.             fMenuBar->Display(ev);
  2221.         }
  2222. }
  2223.  
  2224. //----------------------------------------------------------------------------------------
  2225.  
  2226. void CPPictPart::FocusLost(Environment* ev, ODTypeToken focus, ODFrame* ownerFrame)
  2227. {
  2228.     WeBeHere("\pCPPictPart::FocusLost");
  2229. ODUnused(ownerFrame);
  2230.     if (focus == fMenuFocus)
  2231.     {
  2232.     }
  2233.  
  2234.     if (focus == fSelectionFocus) 
  2235.         {
  2236.         PictPartInfoRec* thisFramePartInfo = (PictPartInfoRec *)ownerFrame->GetPartInfo(ev);
  2237.             if( thisFramePartInfo == nil )
  2238.                 DebugStr("\pthisFramePartInfo == nil in FocusLost !!!");
  2239.         thisFramePartInfo->fIsActive = kODFalse;
  2240.         thisFramePartInfo->fNeedsActivating = kODFalse;
  2241.  
  2242.         if( fPaletteIsOpen )
  2243.             fPaletteWindow->Hide(ev);
  2244.         }
  2245. }
  2246.  
  2247. //----------------------------------------------------------------------------------------
  2248. // Storage protocol
  2249. //----------------------------------------------------------------------------------------
  2250.  
  2251. void CPPictPart::CloneInto(Environment* ev, ODDraftKey key, ODStorageUnit* toSU, ODFrame* scope)
  2252. {
  2253.     WeBeHere("\pCPPictPart::CloneInto");
  2254.  
  2255.     ODStorageUnit*    su = fStorageUnit;
  2256.     ODDraft*        draft = su->GetDraft(ev);
  2257.  
  2258.     ODVolatile(draft);
  2259.  
  2260.     this->Externalize(ev);
  2261.     su->CloneInto(ev, key, toSU, scope->GetStorageUnit(ev)->GetID(ev));
  2262.  
  2263.     if (ev->_major != NO_EXCEPTION)
  2264.         draft->AbortClone(ev, key);
  2265. }
  2266.  
  2267. //----------------------------------------------------------------------------------------
  2268. // Frame protocol
  2269. //----------------------------------------------------------------------------------------
  2270.  
  2271. void CPPictPart::DisplayFrameAdded(Environment* ev, ODFrame* frame)
  2272.  
  2273. // Tells a part to add “frame” as one of its display frames.
  2274. //
  2275. // This method is only called by frame objects during their
  2276. // initialization.  Same for RemoveDisplayFrame() and
  2277. // CloseDisplayFrame().
  2278. //
  2279. // The part must record “frame” in whatever internal structures it
  2280. // uses to remember its display frames. The new frame will carry a
  2281. // suggested viewType and presentation information. The part should
  2282. // look at those settings, and decide if it can support them; if not,
  2283. // it should update those settings in the frame to reflect a default
  2284. // presentation that it can support. Note that the part must support
  2285. // the required set of standard viewTypes (frame, icon, small icon,
  2286. // thumbnail, etc.). The part will then create the appropriate
  2287. // partInfo data and store it in the frame. This data allows the part
  2288. // to distinguish the frame from its other display frames, and is
  2289. // also a handy place to store other view-related information.
  2290. //
  2291. // Add the new display frame to the part’s list of its display frames.
  2292. // This list, like the part’s other internal structures, is completely
  2293. // hidden from OpenDoc. The developer may represent this list any way
  2294. // he chooses. The simplest of parts may be able to do without such a
  2295. // list, but most parts will require it.
  2296. //
  2297. // Validate the viewType and presentation of the new frame. The part
  2298. // must support the required set of view types. Other kinds of view
  2299. // types or presentations are optional. The part should inspect these
  2300. // values and correct them if necessary. See the recipe for View Types
  2301. // and Presentations for more detail.
  2302. //
  2303. // Add partInfo to the frame. The partInfo field of a frame is a
  2304. // convenient place for a part to store information about that view of
  2305. // itself. It can be anything from a simple ID to a pointer to a
  2306. // complicated structure or a helper object. The partInfo for a frame
  2307. // is stored in the storage unit for the frame, not the part. If the
  2308. // part has many frames of which only a few are internalized, only the
  2309. // partInfo of those frames will be internalized and take up memory.
  2310. //
  2311. // The display frames need not be internalized until needed and will be
  2312. // done by the containing part. ???
  2313.  
  2314. {
  2315.     WeBeHere("\pCPPictPart::AddDisplayFrame");
  2316.  
  2317.     fDisplayFrames.Add(frame);
  2318.         // Add new frame to list of current display frames.
  2319.  
  2320.     // PFB
  2321.     if ( frame->GetPart(ev) == fSelf) 
  2322.         {
  2323.         ODTypeToken presentation = frame->GetPresentation(ev);
  2324.         if ((presentation != fPictNormalPresentation) &&
  2325.             (presentation != fPictToolsPresentation))
  2326.             frame->SetPresentation( ev, fPictNormalPresentation );
  2327.         
  2328.  
  2329.         // on crée un part info pour cette frame
  2330.         PictPartInfoRec* thisFramePartInfo = new PictPartInfoRec;
  2331.         // on l'initialise
  2332.         if (frame->IsRoot(ev))
  2333.             thisFramePartInfo->fNeedsActivating = kODTrue;
  2334.         frame->SetPartInfo( ev, (ODInfoType)thisFramePartInfo );
  2335.         frame->SetDroppable( ev, kODTrue );    
  2336.  
  2337.         }
  2338. }
  2339.  
  2340. //----------------------------------------------------------------------------------------
  2341.  
  2342. void CPPictPart::DisplayFrameConnected(Environment* ev, ODFrame* /*frame*/)
  2343. {
  2344.     WeBeHere("\pCPPictPart::DisplayFrameConnected");
  2345.  
  2346.     // // fDisplayFrames.Add(frame);
  2347.     // Don't need to add frame to list of current display frames because we already did
  2348.     // in InitPartFromStorage.
  2349. }
  2350.  
  2351. //----------------------------------------------------------------------------------------
  2352.  
  2353. void CPPictPart::DisplayFrameRemoved(Environment* ev, ODFrame* frame)
  2354.  
  2355. // Removes the frame from the list of display frames.
  2356. //
  2357. // Called by Frame::Remove().
  2358. //
  2359. // This method makes whatever other adjustments are necessary
  2360. // to deal with removing one of the presentations. This includes
  2361. // removing any frames embedded within this display frame.
  2362. // Before calling this method, you must ensure that the frame
  2363. // has no facets.
  2364.  
  2365. {
  2366.     WeBeHere("\pCPPictPart::DisplayFrameRemoved");
  2367.  
  2368.     // PFB
  2369.     if ( frame->GetPart(ev) == fSelf) 
  2370.         {
  2371.         ODTypeToken presentation = frame->GetPresentation(ev);
  2372.         if( presentation == fPictNormalPresentation )
  2373.             {
  2374.             fSession->GetArbitrator(ev)->RelinquishFocusSet(ev, fFocusSet, frame);
  2375.             }
  2376.         else if( presentation == fPictToolsPresentation )
  2377.             {
  2378.             fPaletteIsOpen = kODFalse;
  2379.             fPaletteWindow = nil;
  2380.             fCurrentTool = arrowTool;
  2381.             }
  2382.         }
  2383.  
  2384.     fDisplayFrames.Remove(frame);
  2385.         // This just removes the reference from our frame list.
  2386. }
  2387.  
  2388. //----------------------------------------------------------------------------------------
  2389.  
  2390. void CPPictPart::DisplayFrameClosed(Environment* ev, ODFrame* frame)
  2391.  
  2392. // Informs a part that one of its display frames is closing.
  2393. //
  2394. // Called by the frame object.
  2395. // The part should remove “frame” from its list of display frames,
  2396. // call Frame::Close() on any frames that are embedded within that
  2397. // frame, and then release the frame.
  2398.  
  2399. {
  2400.     WeBeHere("\pCPPictPart::DisplayFrameClosed");
  2401.  
  2402.     if ( frame->GetPart(ev) == fSelf) 
  2403.         {
  2404.         ODTypeToken presentation = frame->GetPresentation(ev);
  2405.         if( presentation == fPictNormalPresentation )
  2406.             {
  2407.             fSession->GetArbitrator(ev)->RelinquishFocusSet(ev, fFocusSet, frame);
  2408.             }
  2409.         else if( presentation == fPictToolsPresentation )
  2410.             {
  2411.             fPaletteIsOpen = kODFalse;
  2412.             fPaletteWindow = nil;
  2413.             fCurrentTool = arrowTool;
  2414.             }
  2415.         }
  2416.  
  2417.     fDisplayFrames.Remove(frame);
  2418.         // This just removes the reference from our frame list.
  2419. }
  2420.  
  2421. //----------------------------------------------------------------------------------------
  2422.  
  2423. void CPPictPart::FrameShapeChanged(Environment* ev, ODFrame* frame)
  2424.  
  2425. // •• Notifies the part that the frame shape of one of its
  2426. // display frames has been changed by its containing part.
  2427. //
  2428. // Called by Frame::ChangeFrameShape.
  2429. //
  2430. // The part should take whatever actions are necessary to respond
  2431. // to the new shape. It may need to re-layout its content, change
  2432. // its used shape, resize its embedded frames, or something else.
  2433. // It also has the option of turning around and asking the frame
  2434. // for a different frame shape via RequestFrameShape, though it
  2435. // must be able to handle the shape it is given. If the size of
  2436. // the frame is not sufficient, the part may ask the containing
  2437. // part for a continuation frame via CreateEmbeddedFrame.
  2438.  
  2439. {
  2440.     WeBeHere("\pCPPictPart::FrameShapeChanged");
  2441.  
  2442.     frame->RequestFrameShape(ev, this->MyGetFrameShape(ev, frame), kODNULL);
  2443.     this->MyAdjustFacets(ev, frame);
  2444.     frame->Invalidate(ev, kODNULL, kODNULL);
  2445.     frame->InvalidateActiveBorder(ev);
  2446. }
  2447.  
  2448. //----------------------------------------------------------------------------------------
  2449.  
  2450. ODShape* CPPictPart::MyGetFrameShape(Environment* ev, ODFrame* frame)
  2451.  
  2452. // This is just to centralize the frame shape code.  Do it any way
  2453. // is best for your part.
  2454.  
  2455. {
  2456.     ODShape* newFrameShape;
  2457.  
  2458.     if (frame->IsRoot(ev))
  2459.         newFrameShape = frame->GetFrameShape(ev, kODNULL);
  2460.     else
  2461.         newFrameShape = this->MyGetUsedShape(ev, frame);
  2462.  
  2463.     return newFrameShape;
  2464. }
  2465.  
  2466. //----------------------------------------------------------------------------------------
  2467.  
  2468. ODShape* CPPictPart::MyGetUsedShape(Environment* ev, ODFrame* frame)
  2469.  
  2470. // This is just to centralize the frame shape code.  Do it any way
  2471. // is best for your part.
  2472.  
  2473. {
  2474.     ODShape* frameShape = frame->GetFrameShape(ev, kODNULL);
  2475.  
  2476.     RgnHandle    shapeRgn = frameShape->CopyQDRegion(ev);
  2477.     ODShape* usedShape = frame->CreateShape(ev);
  2478.     usedShape->SetQDRegion(ev, shapeRgn);
  2479.  
  2480.     return usedShape;
  2481. }
  2482.  
  2483. //----------------------------------------------------------------------------------------
  2484.  
  2485. void CPPictPart::MyAdjustFacets(Environment* ev, ODFrame* frame)
  2486.  
  2487. // Given a frame, iterate through all of the facets and adjust them
  2488. // according to the new frame.
  2489.  
  2490. {
  2491.     ODShape* usedShape  = this->MyGetUsedShape(ev, frame);
  2492.     frame->ChangeUsedShape(ev, usedShape, kODNULL);
  2493.     usedShape->Release(ev);
  2494.  
  2495.     ODShape* frameShape = frame->GetFrameShape(ev, kODNULL);
  2496.     ODFrameFacetIterator* facets = frame->CreateFacetIterator(ev);
  2497.     for (ODFacet* facet = facets->First(ev);
  2498.             facets->IsNotComplete(ev);
  2499.             facet = facets->Next(ev) )
  2500.     {
  2501.         facet->ChangeActiveShape(ev, frameShape, kODNULL);
  2502.     }
  2503.     frameShape->Release(ev);
  2504. }
  2505.  
  2506.  
  2507. //----------------------------------------------------------------------------------------
  2508. /*Adkins*/ 
  2509. void CPPictPart::ClonePartInfo    (Environment *ev, /*Adkins*/
  2510.                                     ODDraftKey key,
  2511.                                     ODInfoType partInfo,
  2512.                                     ODStorageUnitView* storageUnitView,
  2513.                                     ODFrame* scope)
  2514. {
  2515.     WeBeHere("\pCPPictPart::ClonePartInfo");
  2516.     
  2517.     // same thing for us…
  2518.     WritePartInfo( ev, partInfo, storageUnitView );
  2519.     return ;
  2520. }
  2521.  
  2522. //----------------------------------------------------------------------------------------
  2523.  
  2524. void CPPictPart::WritePartInfo(Environment* ev, ODInfoType partInfo,
  2525.                                                        ODStorageUnitView* storageUnitView)
  2526.  
  2527. // Externalizes the frame's partInfo data onto the frame's
  2528. // storage unit.
  2529. //
  2530. // Called by the frame object.
  2531. //
  2532. // Duh???
  2533.  
  2534. {
  2535.     WeBeHere("\pCPPictPart::WritePartInfo");
  2536.  
  2537.     if (partInfo)
  2538.         {
  2539.         ODStorageUnit *storageUnit = storageUnitView->GetStorageUnit(ev);
  2540.         ODPropertyName partInfoProperty = storageUnitView->GetProperty(ev);
  2541.         ODStorageUnit *partInfoStorageUnit;
  2542.  
  2543.         if (storageUnit->Exists(ev, partInfoProperty, kODNULL, 0) == kODFalse)
  2544.             partInfoStorageUnit = storageUnit->AddProperty(ev, partInfoProperty);
  2545.         else
  2546.             partInfoStorageUnit = storageUnit->Focus(ev, partInfoProperty, kODPosUndefined, (ODValueType)kODNULL, 0, kODPosUndefined );
  2547.         if (storageUnit->Exists(ev, partInfoProperty, kPPPropPartInfo, 0) == kODFalse)
  2548.             partInfoStorageUnit->AddValue(ev, kPPPropPartInfo);
  2549.  
  2550.         storageUnit->Focus(ev, partInfoProperty, kODPosUndefined, kPPPropPartInfo, 0, kODPosUndefined);
  2551.         StorageUnitSetValue( storageUnit, ev, sizeof(Point), (ODValue)&(((PictPartInfoRec*)partInfo)->pictureOffset));
  2552.         StorageUnitSetValue( storageUnit, ev, sizeof(int), (ODValue)&(((PictPartInfoRec*)partInfo)->zoomFactor));
  2553.         StorageUnitSetValue( storageUnit, ev, sizeof(Rect), (ODValue)&(((PictPartInfoRec*)partInfo)->activeRect));
  2554.         ODBoolean needsActivating = ((PictPartInfoRec*)partInfo)->fNeedsActivating 
  2555.                                         || ((PictPartInfoRec*)partInfo)->fIsActive;
  2556.         StorageUnitSetValue( storageUnit, ev, sizeof(ODBoolean), (ODValue)&needsActivating);
  2557.         }
  2558.  
  2559. }
  2560.  
  2561.  
  2562. //----------------------------------------------------------------------------------------
  2563.  
  2564.  
  2565. ODInfoType CPPictPart::ReadPartInfo(Environment* ev, ODFrame* frame,
  2566.                                                       ODStorageUnitView* storageUnitView)
  2567.  
  2568. // Internalizes the partInfo for a display frame of this part.
  2569. //
  2570. //
  2571. // Called by the frame object.
  2572. //
  2573. // The data for the partInfo is stored in a value in the frame's
  2574. // storage unit, specified by the suView parameter. It gets the
  2575. // data from out of the value, and places it in a block of memory.
  2576. // It then returns the memory block to the frame for it to hold.
  2577.  
  2578. {
  2579.     WeBeHere("\pCPPictPart::ReadPartInfo");
  2580.  
  2581.     ODStorageUnit *storageUnit = storageUnitView->GetStorageUnit(ev);
  2582.     ODPropertyName partInfoProperty = storageUnitView->GetProperty(ev);
  2583.     PictPartInfoRec* partInfo = new PictPartInfoRec;
  2584.     
  2585.     if (storageUnit->Exists(ev, partInfoProperty, kPPPropPartInfo, 0) )
  2586.         {
  2587.         storageUnit->Focus(ev, partInfoProperty, kODPosUndefined, kPPPropPartInfo, 0, kODPosUndefined);
  2588.         StorageUnitGetValue( storageUnit, ev, sizeof(Point), (ODValue)&(partInfo->pictureOffset));
  2589.         StorageUnitGetValue( storageUnit, ev, sizeof(int), (ODValue)&(partInfo->zoomFactor));
  2590.         StorageUnitGetValue( storageUnit, ev, sizeof(Rect), (ODValue)&(partInfo->activeRect));
  2591.         StorageUnitGetValue( storageUnit, ev, sizeof(ODBoolean), (ODValue)&(partInfo->fNeedsActivating));
  2592.         }
  2593.     else
  2594.         WeBeHere("\p nothing read in ReadPartInfo !!!");
  2595.     frame->SetDroppable(ev, kODTrue);
  2596.  
  2597.     return (ODInfoType)partInfo;
  2598. }
  2599.  
  2600.  
  2601. //-------------------------------------------------------------------------
  2602. // DragAndDrop protocol
  2603. //-------------------------------------------------------------------------
  2604.  
  2605. ODDragResult CPPictPart::DragEnter(Environment* ev, ODDragItemIterator* dragInfo,
  2606.                                                      ODFacet* facet, ODPoint* where)
  2607.  
  2608. // Activates the part used to track the drag.
  2609. //
  2610. // Called by the facet object.
  2611. //
  2612. // The part should display a drag target border within the facet.
  2613. // During drag tracking (DragEnter, DragWithin) the part should
  2614. // never attempt to read data from any of the storage units supplied
  2615. // by the iterator. The part should only inspect the type of the
  2616. // dragged data. Before calling this method, you must ensure that
  2617. // the part is ready to receive DrawWithin messages.
  2618. //
  2619. // DragEnter() is called when the mouse enters a facet.  The part
  2620. // should examine the available data types of the dragged items
  2621. // using the ODDragItemIterator passed in.  If the part can handle
  2622. // a drop of the dragged object, it should provide the appropriate
  2623. // feedback (e.g., adorning the droppable frame, changing the cursor).
  2624. // If the destination part cannot handle the data types, nothing
  2625. // should be done.
  2626.  
  2627. {
  2628.     WeBeHere("\pCPPictPart::DragEnter");
  2629. ODUnused(dragInfo);
  2630. ODUnused(facet);
  2631. ODUnused(where);
  2632.  
  2633. ODStorageUnit *dragSU;
  2634.  
  2635. fAcceptThisDrag = kODFalse;
  2636. fActiveFrameHilitedForDrop = kODFalse;
  2637. for (dragSU = dragInfo->First(ev); dragSU; dragSU = dragInfo->Next(ev))
  2638.     {
  2639.     fAcceptThisDrag = fAcceptThisDrag || ValidDataOnSU( ev,dragSU );
  2640.     }
  2641.  
  2642. return( fAcceptThisDrag );
  2643. }
  2644.  
  2645.  
  2646. //----------------------------------------------------------------------------------------
  2647.  
  2648. ODDragResult CPPictPart::DragWithin(Environment* ev, ODDragItemIterator* dragInfo,
  2649.                                                       ODFacet* facet, ODPoint* where)
  2650.  
  2651. // Tracks the drag operation, and provides graphical feedback
  2652. // regarding possible drop targets.
  2653. //
  2654. // This method highlights the appropriate content to provide
  2655. // feedback about potential drop targets, based on type of dragged
  2656. // data. It gets the type information out of the dragInfo. During
  2657. // drag tracking (DragEnter, DragWithin) the part should never
  2658. // attempt to read data from any of the storage units supplied by
  2659. // the iterator. The part should only inspect the type of the
  2660. // dragged data. Before calling tis method, you must ensure that
  2661. // the part was previously activated via DragEnter().
  2662. //
  2663. // DragWithin() is called continuously when the mouse is still in
  2664. // the facet. This allows the part to do any processing desired.
  2665. // One good example is when the frame has several hot spots where
  2666. // objects can be dropped. If the mouse is not over these hot spots,
  2667. // the cursor may need to be changed to reflect that the no
  2668. // dropping can be done there even though it is still in a
  2669. // droppable frame. Again, a ODDragItemIterator is passed in so
  2670. // that the part can examine the availabe data types of the dragged
  2671. // objects.
  2672. //
  2673. // DragWithin() also provides a chance for the part to examine the
  2674. // state of the machine. For example, some part may want to find
  2675. // out whether the modifier keys are down or not.
  2676.  
  2677. {
  2678.     WeBeHere("\pCPPictPart::DragWithin");
  2679. ODUnused(dragInfo);
  2680. ODUnused(facet);
  2681.  
  2682. ODULong attributes;
  2683. ODFrame* displayFrame;
  2684. PictPartInfoRec* thisFramePartInfo;
  2685. DragReference theDrag;
  2686.  
  2687. attributes = fSession->GetDragAndDrop(ev)->GetDragAttributes(ev);
  2688. theDrag = fSession->GetDragAndDrop(ev)->GetDragReference(ev);
  2689. displayFrame = facet->GetFrame(ev);
  2690. thisFramePartInfo = (PictPartInfoRec*)displayFrame->GetPartInfo(ev);
  2691. if( thisFramePartInfo == nil )
  2692.     DebugStr("\pthisFramePartInfo == nil in DragWithin !!!" );
  2693.  
  2694. if( fAcceptThisDrag )
  2695.     {
  2696.     CFocus myFocus(ev, facet);
  2697.  
  2698.     if( ::PtInRect( where->AsQDPoint(), &thisFramePartInfo->activeRect ) )
  2699.         {
  2700.         if( (fActiveFrameHilitedForDrop == kODFalse) && ((attributes & kODDragIsInSourcePart) == kODFalse) )
  2701.             {
  2702.             RgnHandle dragHiliteRgn;
  2703.             
  2704.             dragHiliteRgn = ::NewRgn();
  2705.             ::RectRgn( dragHiliteRgn, &thisFramePartInfo->activeRect );
  2706.             ShowDragHilite(theDrag, dragHiliteRgn, kODTrue);
  2707.             fActiveFrameHilitedForDrop = kODTrue;
  2708.             }
  2709.         }
  2710.     else if( fActiveFrameHilitedForDrop ) 
  2711.         {
  2712.         HideDragHilite(theDrag);
  2713.         fActiveFrameHilitedForDrop = kODFalse;
  2714.         }
  2715.     }
  2716.  
  2717. return( fAcceptThisDrag );
  2718. }
  2719.  
  2720. //----------------------------------------------------------------------------------------
  2721.  
  2722. void CPPictPart::DragLeave(Environment* ev, ODFacet* facet, ODPoint* where)
  2723.  
  2724. // Signals that the drag operation is complete, and so
  2725. // deactivates the part from drag tracking.
  2726. //
  2727. // This method un-highlights any content previously highlighted
  2728. // during drag tracking. It also removes the drag target border.
  2729. // Before calling this method you must ensure that the part was
  2730. // previously activated via DragEnter().  After executing this
  2731. // method successfully, the part is no longer active, and cannot
  2732. // receive further DragWithin() or Drop() messages.
  2733. //
  2734. // DragLeave() is called when the mouse leaves a droppable frame.
  2735. // This allows the part to clean up after a drag within it
  2736. // (e.g., removing adornment on the frame, changing the cursor
  2737. // back to its original form).
  2738.  
  2739. {
  2740.     WeBeHere("\pCPPictPart::DragLeave");
  2741. ODUnused(facet);
  2742.  
  2743. ODULong attributes;
  2744. ODPoint windowWhere;
  2745. ODFrame* displayFrame;
  2746. PictPartInfoRec* thisFramePartInfo;
  2747. DragReference theDrag;
  2748.  
  2749. attributes = fSession->GetDragAndDrop(ev)->GetDragAttributes(ev);
  2750. theDrag = fSession->GetDragAndDrop(ev)->GetDragReference(ev);
  2751. windowWhere = facet->GetWindowFrameTransform(ev, kODNULL)->TransformPoint(ev,where);
  2752. displayFrame = facet->GetFrame(ev);
  2753. thisFramePartInfo = (PictPartInfoRec*)displayFrame->GetPartInfo(ev);
  2754.  
  2755. // && (attributes & kODDragHasLeftSourceFrame)
  2756. if( fAcceptThisDrag )
  2757.     {
  2758.     CFocus myFocus(ev, facet);
  2759.     if (fActiveFrameHilitedForDrop ) 
  2760.         {
  2761.         HideDragHilite(theDrag);
  2762.         fActiveFrameHilitedForDrop = kODFalse;
  2763.         }
  2764.     }
  2765. }
  2766.  
  2767. //----------------------------------------------------------------------------------------
  2768.  
  2769. ODDropResult CPPictPart::Drop(Environment* ev, ODDragItemIterator* dropInfo,
  2770.                                                 ODFacet* facet, ODPoint* where)
  2771.  
  2772. // Transfers the dragged data into this part.
  2773. //
  2774. // Called by the facet object.
  2775. //
  2776. // Respond to the Drop operation. This might involve moving or
  2777. // copying data in to the part, or some other response entirely.
  2778. // However, the response should use the data returned from the
  2779. // dropInfo iterator to perform the operation. Before calling
  2780. // this method, you must ensure that the part was previously
  2781. // activated via DragEnter().
  2782. //
  2783. // Don't forget whether the drop is a move or a copy.
  2784. //
  2785. // Drop() is called when the mouse is released within a part which
  2786. // owns the facet. The part can then figure out whether it can
  2787. // receive the dragged object using the ODDragItemIterator passed
  2788. // in. The following is a sample code fragment for incorporating
  2789. // text into a part.
  2790. //
  2791. // The destination part should return an appropriate ODDropResult
  2792. // from Drop(). This result tells the source part (via the system)
  2793. // whether the drop is accepted.
  2794.  
  2795. {
  2796.     WeBeHere("\pCPPictPart::Drop");
  2797. ODUnused(dropInfo);
  2798. ODUnused(facet);
  2799. ODUnused(where);
  2800.  
  2801. ODDropResult theResult = kODDropFail;
  2802. if( fActiveFrameHilitedForDrop )
  2803.     {
  2804.     ODULong attributes;
  2805.     DragReference theDrag;
  2806.     short mouseDownModifiers;
  2807.     short mouseUpModifiers;
  2808.     ODStorageUnit *dropSU;
  2809.     Boolean moveData = kODFalse;
  2810.     Boolean useLinkInfo = kODFalse;
  2811.     Handle dropPicHandle;
  2812.     Boolean gotSomething = kODFalse;
  2813.  
  2814.     attributes = fSession->GetDragAndDrop(ev)->GetDragAttributes(ev);
  2815.     theDrag = fSession->GetDragAndDrop(ev)->GetDragReference(ev);
  2816.     GetDragModifiers(theDrag, 0L, &mouseDownModifiers, &mouseUpModifiers);
  2817.     // If option key is held down at mousedown, it is a force-copy.
  2818.     if (mouseDownModifiers & optionKey)
  2819.         moveData = kODFalse;
  2820.     // If cmd key is held down at mousedown, it is a force-move.
  2821.     else if (mouseDownModifiers & cmdKey)
  2822.         useLinkInfo = kODTrue;
  2823.     // If option key is held down at mouseUp, it is a force-copy.
  2824.     else if (mouseUpModifiers & optionKey)
  2825.         moveData = kODFalse;
  2826.     // If cmd key is held down at mouseUp, it is a force-move.
  2827.     else if (mouseUpModifiers & cmdKey)
  2828.         useLinkInfo = kODTrue;
  2829.  
  2830.     dropPicHandle = nil;
  2831.     for (dropSU = dropInfo->First(ev); (dropSU && gotSomething == kODFalse); dropSU = dropInfo->Next(ev))
  2832.         {
  2833.         if( useLinkInfo )
  2834.             {
  2835.             if( ValidLinkOnSU( ev, dropSU ) )
  2836.                 {
  2837.                 ODFrameFacetIterator* facets = (ODFrameFacetIterator*) kODNULL;
  2838.                 ODPasteAsResult pasteAsRslt;
  2839.                 
  2840.                 pasteAsRslt.pasteLinkSetting = kODTrue;
  2841.                 if ( fSession->GetDragAndDrop(ev)->ShowPasteAsDialog(ev, 
  2842.                                 kODTrue,
  2843.                                 kODFalse,
  2844.                                 facet,
  2845.                                 fSession->Tokenize(ev, kODViewAsFrame),
  2846.                                 dropSU,
  2847.                                 &pasteAsRslt) )
  2848.                     {
  2849.                     // Cannot paste a link if translation is required
  2850.                     if ( pasteAsRslt.translateKind != kODNULL )
  2851.                         DebugStr("\pcannot translate !!!");
  2852.                     InternalizeLinkFromSU(ev, dropSU, &pasteAsRslt );
  2853.                     }
  2854.                 if( pasteAsRslt.pasteLinkSetting == kODTrue )
  2855.                     theResult = kODDropMove;
  2856.                 }
  2857.             }
  2858.         gotSomething = InternalizeFromSU( ev, dropSU, facet->GetFrame(ev) );
  2859.         if( gotSomething && (useLinkInfo == kODFalse) )
  2860.             RemoveDestLink( ev );
  2861.         if( moveData )
  2862.             theResult = kODDropMove;
  2863.         else
  2864.             theResult = kODDropCopy;
  2865.         }
  2866.     fAcceptThisDrag = kODFalse;
  2867.     }
  2868. return theResult;
  2869. }
  2870.  
  2871.  
  2872. //----------------------------------------------------------------------------------------
  2873. // From Linking protocol
  2874. //----------------------------------------------------------------------------------------
  2875.  
  2876. ODLinkSource* CPPictPart::CreateLink(Environment* ev, ODByteArray* data)
  2877.  
  2878. // Creates a new link object.
  2879. //
  2880. // If a link already exists to the content identified by the data
  2881. // and size arguments, this method returns the link object;
  2882. // otherwise, it creates a new link object, puts in the initial
  2883. // data and returns it to the caller.
  2884. //
  2885. // This method identifies the content to be linked (by resolving
  2886. // the object specifier saved in the data parameter, or by some
  2887. // other means). It then creates a link object to represent the
  2888. // content data. The part must maintain information about what
  2889. // portion of its contents have been linked to it, so that it may
  2890. // notify link clients when that data has been changed. The link
  2891. // created is returned to the caller. Before calling this method,
  2892. // you must ensure that the data identifies some portion of this
  2893. // part's contents. After calling this method successfully, this
  2894. // part maintains a link to the identified content.
  2895.  
  2896. {
  2897.     WeBeHere("\pCPPictPart::CreateLink");
  2898.  
  2899.     // Call a part-specific method to get the link if it already exists
  2900.     ODLinkSource* linkSource = fSrcLink;
  2901.     
  2902.     if (linkSource == kODNULL)
  2903.     {
  2904.         // Call this part's draft to create both the link source object
  2905.         //   used by this part, and the link object returned from this
  2906.         //   method and used by destinations of the link.
  2907.  
  2908.         linkSource = fSelf->GetStorageUnit(ev)->GetDraft(ev)->
  2909.                             CreateLinkSource(ev, fSelf);
  2910.         // Add the link to the content model of this part.
  2911.         fSrcLink = linkSource;
  2912.         
  2913.         ODLinkKey key;
  2914.         ODVolatile(linkSource);
  2915.         ODVolatile(key);
  2916.         TRY
  2917.             if (linkSource->Lock(ev, 0, &key))
  2918.             {
  2919.             TRY
  2920.                 ODStorageUnit* linkContentSU = 
  2921.                     linkSource->GetContentStorageUnit(ev, key);
  2922.  
  2923.                 PrepareSU( ev, linkContentSU );
  2924.                 ExternalizeToSU( ev, linkContentSU );
  2925.                 // A new change ID is used to update the link the first time.
  2926.                 ODChangeID change = fSession->UniqueChangeID(ev);
  2927.                 linkSource->ContentChanged(ev, change, key);
  2928.                 fSrcLinkChange = change;
  2929.                 linkSource->Unlock(ev, key);
  2930.  
  2931.             CATCH_ALL
  2932.  
  2933.                 DebugStr("\pexception at CreateLink !!!");
  2934.                 linkSource->Unlock(ev, key);
  2935.                 RERAISE;
  2936.             ENDTRY
  2937.             }
  2938.         CATCH( kODErrBrokenLinkSource )
  2939.             DebugStr("\pPictPart: ODLinkSource::Lock() returned broken link error\n");
  2940.             RemoveSourceLink(ev);
  2941.         ENDTRY
  2942.     }
  2943.     
  2944.  
  2945.     // change link status of my frames
  2946.     for (FrameLink *fl = fDisplayFrames.First(); fl->Frame(); fl = fl->Next())
  2947.         {
  2948.         if (fl->Frame()->GetPresentation(ev) == fPictNormalPresentation )
  2949.             fl->Frame()->ChangeLinkStatus( ev, kODInLinkSource );
  2950.         }
  2951.  
  2952.     // update all my facets
  2953.     MySetDirty(ev);
  2954.     MyInvalAllDisplayFrames( ev );
  2955.     
  2956.  
  2957.     return linkSource;
  2958.  
  2959. }
  2960.  
  2961. //----------------------------------------------------------------------------------------
  2962.  
  2963. void CPPictPart::LinkUpdated(Environment* ev, ODLink* updatedLink, ODChangeID id)
  2964.  
  2965. // Retrieves the data from the link and incorporates it into
  2966. // this part at the link's destination, thereby replacing any
  2967. // previous content of the link.
  2968.  
  2969. {
  2970.     WeBeHere("\pCPPictPart::LinkUpdated");
  2971.     ODUnused(id);
  2972.  
  2973.     ODStorageUnit*     su;
  2974.     ODLinkKey         key;
  2975.     ODBoolean        gotSomething = kODFalse;
  2976.     
  2977. if (updatedLink->Lock(ev, 0, &key))
  2978.     {
  2979.     su = updatedLink->GetContentStorageUnit(ev, key);
  2980.     if( ValidDataOnSU( ev, su ) )
  2981.         {
  2982.         gotSomething = InternalizeFromSU( ev, su );
  2983.         fDestLinkInfo.change = fDestLink->GetChangeID(ev);
  2984.         fDestLinkInfo.changeTime = fDestLink->GetChangeTime(ev);
  2985.         }
  2986.     updatedLink->Unlock(ev, key);
  2987.     if( gotSomething )    
  2988.         MyInvalAllDisplayFrames( ev );
  2989.     }
  2990. }
  2991.  
  2992. //----------------------------------------------------------------------------------------
  2993.  
  2994. void CPPictPart::RevealLink(Environment* ev, ODLinkSource* linkSource)
  2995.  
  2996. // Reveals data that was previously linked in a window, making it
  2997. // available for viewing in a display frame.
  2998. //
  2999. // Called by ODLinkSource objects.  Should not be called by parts.
  3000. // In some display frame for this part, this method selects the
  3001. // content linked by the linkSource argument, and scrolls it into
  3002. // view. That display frame is made the active frame. If no display
  3003. // frames for the part currently exist, or if this part's containing
  3004. // frame can't reveal the display frame, it opens a frame in a new
  3005. // window.
  3006.  
  3007. {
  3008.     WeBeHere("\pCPPictPart::RevealLink");
  3009.  
  3010.     if( linkSource != fSrcLink )
  3011.         return;
  3012.  
  3013.     ODFrame* frame = fDisplayFrames.First()->Frame();
  3014.     
  3015.     if ( frame != (ODFrame*) kODNULL )
  3016.         {
  3017.         ProcessSerialNumber psn;
  3018.         GetCurrentProcess(&psn);
  3019.         SetFrontProcess(&psn);
  3020.  
  3021.         ODFrame* containingFrame = frame->GetContainingFrame(ev);
  3022.  
  3023.         if ( containingFrame != (ODFrame*) kODNULL )
  3024.             {
  3025.             // Sample parts currently THROW so catch and ignore
  3026.             TRY
  3027.                 containingFrame->GetPart(ev)->RevealFrame(ev, frame, (ODShape*) kODNULL);
  3028.             CATCH_ALL
  3029.             ENDTRY
  3030.             }
  3031.  
  3032.         // Try to grab all of our foci…
  3033.         if ( fSession->GetArbitrator(ev)->RequestFocusSet(ev, fFocusSet,frame) )
  3034.             {
  3035.             this->FocusAcquired(ev, fSelectionFocus, frame);
  3036.             this->FocusAcquired(ev, fMenuFocus, frame);
  3037.             this->FocusAcquired(ev, fKeyFocus, frame);
  3038.             
  3039.             ODFrameFacetIterator* facets = frame->CreateFacetIterator(ev);
  3040.             for (ODFacet* facet = facets->First(ev);
  3041.                     facets->IsNotComplete(ev);
  3042.                     facet = facets->Next(ev) )
  3043.             {
  3044.                 CFocus myFocus( ev, facet );
  3045.                 long finalTicks;
  3046.                 PictPartInfoRec* thisFramePartInfo = (PictPartInfoRec*)frame->GetPartInfo(ev);
  3047.         
  3048.                 InvertRect( &thisFramePartInfo->activeRect );
  3049.                 Delay( 10, &finalTicks );
  3050.                 InvertRect( &thisFramePartInfo->activeRect );
  3051.             }
  3052.  
  3053.             }
  3054.         }
  3055. }
  3056.  
  3057.  
  3058. //----------------------------------------------------------------------------------------
  3059.  
  3060.  
  3061. // PFB
  3062.  
  3063. void CPPictPart::UpdateSourceLink( Environment* ev, Boolean forceUpdate )
  3064. {
  3065.  
  3066. if( fSrcLink != kODNULL )
  3067.     {
  3068.     ODLinkKey linkKey;
  3069.     ODLinkSource* linkSource = fSrcLink;
  3070.     ODChangeID changeID = fSrcLinkChange;
  3071.     
  3072.     ODVolatile(linkSource);
  3073.     ODVolatile(linkKey);
  3074.  
  3075.     WeBeHere("\pin UpdateSourceLink…" );
  3076.  
  3077.     if( forceUpdate || fSrcLink->IsAutoUpdate(ev) )
  3078.         {
  3079.  
  3080.         TRY
  3081.         if ( linkSource->Lock(ev, 0, &linkKey) )
  3082.             {
  3083.             TRY
  3084.                                             
  3085.                 ODStorageUnit* linkContentSU = linkSource->GetContentStorageUnit(ev, linkKey);        
  3086.                 // Begin a transaction if objects are cloned into the link
  3087.                 ODDraftKey draftKey = 0;
  3088.                 ODVolatile(fDraft);
  3089.                 ODVolatile(draftKey);        
  3090.                 TRY
  3091.                     draftKey = fDraft->BeginClone(ev,
  3092.                                             linkContentSU->GetDraft(ev),
  3093.                                             kODCloneToLink);
  3094.                     // For each value in the link, focus and rewrite
  3095.                     //   This is part specific
  3096.                     PrepareSU( ev, linkContentSU );
  3097.                     ExternalizeToSU( ev, linkContentSU );
  3098.         
  3099.                     fDraft->EndClone(ev, draftKey);
  3100.         
  3101.                 CATCH_ALL
  3102.         
  3103.                     if (draftKey != 0 )
  3104.                         fDraft->AbortClone(ev, draftKey);
  3105.                     RERAISE;
  3106.         
  3107.                 ENDTRY
  3108.         
  3109.                 // Inform the link that it has changed, so destinations can
  3110.                 //   update.  The changeID parameter should be the change
  3111.                 //   causing the link to update.
  3112.         
  3113.                 linkSource->ContentChanged(ev, changeID, linkKey);
  3114.                 linkSource->Unlock(ev, linkKey);
  3115.         
  3116.             CATCH_ALL
  3117.         
  3118.                 // Clear a partially-updated link
  3119.                 DebugStr("\pexception at UpdateSourceLink !!!");
  3120.                 linkSource->Clear(ev, fSession->UniqueChangeID(ev), linkKey);
  3121.                 linkSource->Unlock(ev, linkKey);
  3122.         
  3123.             ENDTRY
  3124.             }
  3125.         else
  3126.             {
  3127.             DebugStr("\pcannot lock !!!");
  3128.             }
  3129.         CATCH(kODErrBrokenLinkSource)
  3130.             DebugStr("\pPictPart: ODLinkSource::Lock() returned broken link error\n");
  3131.             RemoveSourceLink(ev);
  3132.         ENDTRY
  3133.         }
  3134.     }
  3135. }
  3136.  
  3137. void CPPictPart::RemoveSourceLink( Environment* ev )
  3138. {
  3139. if( fSrcLink != kODNULL )
  3140.     {
  3141.  
  3142.     WeBeHere("\pin RemoveSourceLink…" );
  3143.  
  3144.     ODLinkSource* linkSource = fSrcLink;
  3145.     fSrcLink = kODNULL;
  3146.     fSrcLinkChange = kODUnknownChange;
  3147.  
  3148.     ODLinkKey linkKey;
  3149.     if ( linkSource->Lock(ev, 0, &linkKey) )
  3150.         {
  3151.         linkSource->ContentChanged(ev, kODUnknownChange, linkKey);
  3152.         linkSource->Unlock(ev, linkKey);
  3153.         }
  3154.  
  3155.     linkSource->SetSourcePart(ev, kODNULL);
  3156.     linkSource->Release(ev);
  3157.     
  3158.     for (FrameLink *fl = fDisplayFrames.First(); fl->Frame(); fl = fl->Next())
  3159.         fl->Frame()->ChangeLinkStatus( ev, kODNotInLink );
  3160.  
  3161.     MySetDirty( ev );
  3162.     MyInvalAllDisplayFrames(ev);
  3163.     }
  3164. }
  3165.  
  3166. void CPPictPart::RemoveDestLink( Environment* ev )
  3167. {
  3168. if( fDestLink != kODNULL )
  3169.     {
  3170.  
  3171.     WeBeHere("\pin RemoveDestLink…" );
  3172.  
  3173.     if ( fDestLinkInfo.autoUpdate )
  3174.         fDestLink->UnregisterDependent(ev, fSelf );
  3175.     fDestLink->Release(ev);
  3176.     fDestLink = kODNULL;
  3177.  
  3178.     for (FrameLink *fl = fDisplayFrames.First(); fl->Frame(); fl = fl->Next())
  3179.         fl->Frame()->ChangeLinkStatus( ev, kODNotInLink );
  3180.  
  3181.     MySetDirty( ev );
  3182.     MyInvalAllDisplayFrames(ev);
  3183.     }
  3184. }
  3185.  
  3186. void CPPictPart::AdjustCursor( Environment* ev, PictPartInfoRec* framePartInfo )
  3187. {
  3188. CUsingLibraryResources fil;
  3189.  
  3190.     WeBeHere("\pPictPart::AdjustCursor");
  3191.  
  3192. if( fCurrentCursorHandle != nil )
  3193.     {
  3194.     ::HUnlock( (Handle)fCurrentCursorHandle );
  3195.     ::DisposeHandle( (Handle)fCurrentCursorHandle );
  3196.     fCurrentCursorHandle = nil;
  3197.     }
  3198. switch( fCurrentTool )
  3199.     {
  3200.     case arrowTool:
  3201.         ::SetCursor(&ODQDGlobals.arrow);
  3202.         break;
  3203.     case zoomInTool:
  3204.         if( framePartInfo->IsZoomingInAllowed() )
  3205.             fCurrentCursorHandle = ::GetCursor( zoomInCursorRsrcId );
  3206.         else
  3207.             fCurrentCursorHandle = ::GetCursor( noZoomCursorRsrcId );
  3208.         break;
  3209.     case zoomOutTool:
  3210.         if( framePartInfo->IsZoomingOutAllowed() )
  3211.             fCurrentCursorHandle = ::GetCursor( zoomOutCursorRsrcId );
  3212.         else
  3213.             fCurrentCursorHandle = ::GetCursor( noZoomCursorRsrcId );
  3214.         break;
  3215.     case moveTool:
  3216.         fCurrentCursorHandle = ::GetCursor( handCursorRsrcId );
  3217.         break;
  3218.     }
  3219. if( fCurrentCursorHandle != nil )
  3220.     {
  3221.     ::DetachResource( (Handle)fCurrentCursorHandle );
  3222.     ::HLock( (Handle)fCurrentCursorHandle );
  3223.     ::SetCursor( *fCurrentCursorHandle );
  3224.     }
  3225. }
  3226.  
  3227.  
  3228.  
  3229. void CPPictPart::PrepareSU( Environment* ev, ODStorageUnit *storageUnit )
  3230. {
  3231. ODStorageUnit *pictPartContentSU;
  3232.  
  3233. if (storageUnit->Exists(ev, kODPropContents, kODNULL, 0) == kODFalse)
  3234.     pictPartContentSU = storageUnit->AddProperty(ev, kODPropContents);
  3235. else
  3236.     pictPartContentSU = storageUnit->Focus(ev, kODPropContents, kODPosUndefined, (ODValueType)kODNULL, 0, kODPosUndefined );
  3237. if( fExternalizeOnlyPICTFormat == kODFalse )
  3238.     {
  3239.     if (storageUnit->Exists(ev, kODPropContents, kPictPartKind, 0) == kODFalse)
  3240.         pictPartContentSU->AddValue(ev, kPictPartKind);
  3241.     }
  3242. if (storageUnit->Exists(ev, kODPropContents, kODApplePICT, 0) == kODFalse)
  3243.     pictPartContentSU->AddValue(ev, kODApplePICT);
  3244.     
  3245. }
  3246.  
  3247. void CPPictPart::ExternalizeToSU( Environment* ev, ODStorageUnit *storageUnit,
  3248.                                                 ODFrame *frame )
  3249. {
  3250.  
  3251.     WeBeHere("\pPictPart::ExternalizeToSU");
  3252.  
  3253. PictPartInfoRec* thisFramePartInfo;
  3254.  
  3255. if( fPicture == nil )
  3256.     return;
  3257.  
  3258. if( frame != nil )
  3259.     thisFramePartInfo = (PictPartInfoRec *)frame->GetPartInfo(ev);
  3260. else
  3261.     thisFramePartInfo = new PictPartInfoRec; // for default values
  3262.  
  3263. // private format
  3264. if( fExternalizeOnlyPICTFormat == kODFalse )
  3265.     {
  3266.     storageUnit->Focus(ev, kODPropContents, kODPosUndefined, kPictPartKind, 0, kODPosUndefined);
  3267.     ::HLock( fPicture );
  3268.     StorageUnitSetValue( storageUnit, ev, ::GetHandleSize( fPicture ), (ODValue)*fPicture);
  3269.     StorageUnitSetValue( storageUnit, ev, sizeof(Point), (ODValue)&(thisFramePartInfo->pictureOffset));
  3270.     StorageUnitSetValue( storageUnit, ev, sizeof(int), (ODValue)&(thisFramePartInfo->zoomFactor));
  3271.     ::HUnlock( fPicture );
  3272.     }
  3273. // universal PICT ???
  3274. storageUnit->Focus(ev, kODPropContents, kODPosUndefined, kODApplePICT, 0, kODPosUndefined );
  3275. ::HLock( fPicture );
  3276. StorageUnitSetValue( storageUnit, ev, ::GetHandleSize( fPicture ), (ODValue)*fPicture);
  3277. ::HUnlock( fPicture );
  3278.  
  3279. if( frame == nil )
  3280.     delete thisFramePartInfo;
  3281.  
  3282. }
  3283.  
  3284. ODBoolean CPPictPart::InternalizeFromSU( Environment* ev, ODStorageUnit *storageUnit, ODFrame *frame)
  3285. {
  3286.  
  3287.     WeBeHere("\pPictPart::InternalizeFromSU");
  3288.  
  3289. Handle suPicHandle;
  3290. long valueSize;
  3291. ODBoolean gotSomething = kODFalse;
  3292.  
  3293. if (storageUnit->Exists(ev, kODPropContents, kPictPartKind, 0))
  3294.     {
  3295.     storageUnit->Focus( ev, kODPropContents, kODPosUndefined, kPictPartKind, 0, kODPosUndefined);
  3296.     valueSize = storageUnit->GetSize(ev) - sizeof(Point) - sizeof(int);
  3297.     suPicHandle = ::NewHandle( valueSize );
  3298.     THROW_IF_NULL( suPicHandle );
  3299.     ::HLock( suPicHandle );
  3300.     StorageUnitGetValue( storageUnit, ev, valueSize, (ODValue)*suPicHandle);
  3301.     ::HUnlock( suPicHandle );
  3302.     if( frame != nil )
  3303.         {
  3304.         PictPartInfoRec* thisFramePartInfo = (PictPartInfoRec *)frame->GetPartInfo(ev);
  3305.             if( thisFramePartInfo == nil )
  3306.                 DebugStr("\pthisFramePartInfo == nil in InternalizeFromSU !!!");
  3307.         StorageUnitGetValue( storageUnit, ev, sizeof(Point), (ODValue)&(thisFramePartInfo->pictureOffset));
  3308.         StorageUnitGetValue( storageUnit, ev, sizeof(int), (ODValue)&(thisFramePartInfo->zoomFactor));
  3309.         }
  3310.     if( fPicture != nil )
  3311.         ::DisposeHandle( fPicture );
  3312.     fPicture = suPicHandle;
  3313.     gotSomething = kODTrue;
  3314.     }
  3315. else if (storageUnit->Exists(ev, kODPropContents, kODApplePICT, 0))
  3316.     {
  3317.     storageUnit->Focus(ev, kODPropContents, kODPosUndefined, kODApplePICT, 0, kODPosUndefined);
  3318.     valueSize = storageUnit->GetSize(ev);
  3319.     suPicHandle = ::NewHandle( valueSize );
  3320.     THROW_IF_NULL( suPicHandle );
  3321.     ::HLock( suPicHandle );
  3322.     StorageUnitGetValue( storageUnit, ev, valueSize, (ODValue)*suPicHandle);
  3323.     ::HUnlock( suPicHandle );
  3324.     // store picture and reinit part info (zoom offset,etc… );
  3325.     if( fPicture != nil )
  3326.         ::DisposeHandle( fPicture );
  3327.     fPicture = suPicHandle;
  3328.     gotSomething = kODTrue;
  3329.     }
  3330. else if( storageUnit->Exists( ev, kODPropContents, kODApplehfs, 0) )
  3331.     {
  3332.     long fileSize;
  3333.     Ptr fileData;
  3334.     short fileRefNum;
  3335.     
  3336.     storageUnit->Focus(ev, kODPropContents, kODPosUndefined, kODApplehfs, 0, kODPosUndefined);        
  3337.     fileSize = storageUnit->GetSize(ev);        // really hfsflavor size
  3338.     fileData = ::NewPtr( fileSize );            // really hfsflavor data
  3339.     THROW_IF_NULL( fileData );
  3340.     StorageUnitGetValue( storageUnit, ev, fileSize, (ODValue)fileData);
  3341.     
  3342.     THROW_IF_ERROR(::FSpOpenDF((FSSpec*)&(((HFSFlavor*)fileData)->fileSpec), fsRdPerm, &fileRefNum));
  3343.     THROW_IF_ERROR(::GetEOF(fileRefNum,&valueSize));
  3344.     if (valueSize == 0)
  3345.         THROW(kODErrUndefined);
  3346.     valueSize -= 512;
  3347.     suPicHandle = ::NewHandle( valueSize );
  3348.     THROW_IF_NULL( suPicHandle );
  3349.     ::HLock( suPicHandle );
  3350.     THROW_IF_ERROR(::SetFPos(fileRefNum,fsFromStart, 512));
  3351.     THROW_IF_ERROR(::FSRead(fileRefNum,&valueSize,*suPicHandle));
  3352.     THROW_IF_ERROR(::FSClose(fileRefNum));
  3353.     ::DisposePtr( fileData );
  3354.     ::HUnlock( suPicHandle );
  3355.     // store picture and reinit part info (zoom offset,etc… );
  3356.     if( fPicture != nil )
  3357.         ::DisposeHandle( fPicture );
  3358.     fPicture = suPicHandle;
  3359.     gotSomething = kODTrue;
  3360.     }
  3361. if( gotSomething )
  3362.     {
  3363.     MySetDirty(ev);
  3364.     UpdateSourceLink( ev, false );
  3365.     MyInvalAllDisplayFrames(ev);
  3366.     }
  3367. else
  3368.     {
  3369.     WeBeHere("\pgot nothing …");
  3370.     }
  3371.  
  3372. return( gotSomething );
  3373. }
  3374.  
  3375. const ODISOStr            kDummyLinkSpecData = "LinkSpec dummy data";
  3376.  
  3377. void CPPictPart::ExternalizeLinkToSU( Environment* ev, ODStorageUnit *storageUnit )
  3378. {
  3379. // Add a link spec to the storage unit if we don't already have a source link
  3380. // (or the source link is selected exactly),
  3381. // and as long as the selection does not include a link destination.
  3382. // Also, don't add a link spec if draft permissions don't allow writing.
  3383.  
  3384.     WeBeHere("\pPictPart::ExternalizeLinkToSU");
  3385.  
  3386. ODBoolean makeLinkSpec = kODFalse;
  3387.  
  3388. if( fExternalizeOnlyPICTFormat == kODFalse )
  3389.     {
  3390.     if ( fDraft->GetPermissions(ev) >= kDPSharedWrite )
  3391.         {
  3392.         if (fSrcLink == (ODLinkSource*) kODNULL)
  3393.             {
  3394.             if (fDestLink == (ODLink*) kODNULL)
  3395.                 {
  3396.                 makeLinkSpec = kODTrue;
  3397.                 }
  3398.             }        
  3399.         else
  3400.             makeLinkSpec = kODTrue;
  3401.         }
  3402.     
  3403.     if (makeLinkSpec)
  3404.         {
  3405.         storageUnit->AddProperty(ev, kODPropLinkSpec);
  3406.         ODByteArray data = CreateByteArrayStruct(kDummyLinkSpecData, ODISOStrLength(kDummyLinkSpecData));        
  3407.         ODLinkSpec* linkSpec = fDraft->CreateLinkSpec(ev, fSelf, &data);
  3408.         linkSpec->WriteLinkSpec(ev, storageUnit);
  3409.         DisposeByteArrayStruct(data);
  3410.         delete linkSpec;
  3411.         }
  3412.     }
  3413. }
  3414.  
  3415. ODBoolean CPPictPart::InternalizeLinkFromSU( Environment* ev, ODStorageUnit *storageUnit, 
  3416.                                 ODPasteAsResult *pasteAsResult )
  3417. {
  3418.  
  3419.     WeBeHere("\pPictPart::InternalizeLinkFromSU");
  3420.  
  3421. if( storageUnit->Exists(ev, kODPropLinkSpec, (ODValueType) kODNULL, 0) ) 
  3422.     {
  3423.     ODLinkSpec* linkSpec = fDraft->CreateLinkSpec(ev, fSelf, 0);
  3424.     storageUnit->Focus(ev, kODPropLinkSpec, kODPosUndefined, (ODValueType)kODNULL, 0, kODPosUndefined);
  3425.     linkSpec->ReadLinkSpec(ev, storageUnit);
  3426.     TRY
  3427.         {
  3428.         fDestLink = fDraft->GetLink(ev, (ODStorageUnitID) kODNULL, linkSpec);
  3429.         if (fDestLink != (ODLink*) kODNULL)
  3430.             {
  3431.             fDestLinkInfo.change = fDestLink->GetChangeID(ev);
  3432.             GetDateTime((ODTime*) &fDestLinkInfo.creationTime);
  3433.             fDestLinkInfo.changeTime = fDestLinkInfo.creationTime;
  3434.             fDestLinkInfo.kind = pasteAsResult->selectedKind;
  3435.             fDestLinkInfo.autoUpdate = pasteAsResult->autoUpdateSetting;
  3436.  
  3437.             for (FrameLink *fl = fDisplayFrames.First(); fl->Frame(); fl = fl->Next())
  3438.                 {
  3439.                 if (fl->Frame()->GetPresentation(ev) == fPictNormalPresentation )
  3440.                     fl->Frame()->ChangeLinkStatus( ev, kODInLinkDestination );
  3441.                 }
  3442.             
  3443.             // Now register as a dependent of the link
  3444.             // Specify kODUnknownChange to force getting the text.
  3445.             // By default the destination is automatically updated.
  3446.             if( fDestLinkInfo.autoUpdate )
  3447.                 fDestLink->RegisterDependent(ev, fSelf, kODUnknownChange);
  3448.             fDraft->SetChangedFromPrev(ev);
  3449.             }
  3450.         else
  3451.             SysBeep( 30 );
  3452.         }
  3453.     CATCH_ALL
  3454.         DebugStr("\pexception at InternalizeLinkFromSU!!!");
  3455.     ENDTRY
  3456.     delete linkSpec;
  3457.     }
  3458. return kODFalse;
  3459. }
  3460.  
  3461. ODBoolean CPPictPart::ValidDataOnSU( Environment* ev, ODStorageUnit *storageUnit)
  3462. {
  3463.  
  3464.     WeBeHere("\pPictPart::ValidDataOnSU");
  3465.  
  3466. HFSFlavor *valueData;
  3467. long valueSize;
  3468. ODBoolean validDataWasFound = kODFalse;
  3469.  
  3470. if ( storageUnit->Exists( ev, kODPropContents, kODApplePICT, 0) || 
  3471.      storageUnit->Exists( ev, kODPropContents, kPictPartKind, 0) )
  3472.     {
  3473.     validDataWasFound = kODTrue;
  3474.     }
  3475. else
  3476.     {
  3477.     if ( storageUnit->Exists(ev, kODPropContents, kODApplehfs, 0) )
  3478.         {
  3479.         storageUnit->Focus( ev, kODPropContents, kODPosUndefined, kODApplehfs, 0, kODPosUndefined );        
  3480.         valueSize = storageUnit->GetSize(ev);
  3481.         valueData = (HFSFlavor *)::NewPtr(valueSize);
  3482.         if (valueData)
  3483.             {
  3484.             StorageUnitGetValue( storageUnit, ev, valueSize, (ODValue)valueData);
  3485.             if ((valueData->fileType == 'PICT') )                    // sEXT = TeachText stationery
  3486.                 validDataWasFound = kODTrue;
  3487.             }
  3488.         ::DisposePtr((Ptr)valueData);
  3489.         }
  3490.     }
  3491. return( validDataWasFound );
  3492. }
  3493.  
  3494. ODBoolean CPPictPart::ValidLinkOnSU( Environment* ev, ODStorageUnit *storageUnit)
  3495. {
  3496.  
  3497.     WeBeHere("\pPictPart::ValidLinkOnSU");
  3498.  
  3499. ODBoolean validDataWasFound = kODFalse;
  3500.  
  3501. if ( storageUnit->Exists(ev, kODPropLinkSpec, (ODValueType) kODNULL, 0) )
  3502.     {
  3503.     validDataWasFound = kODTrue;
  3504.     }
  3505. return( validDataWasFound );
  3506. }
  3507.  
  3508. Rect CPPictPart::CalcPictureRect( Environment* ev, PictPartInfoRec* framePartInfo )
  3509. {
  3510.  
  3511. if( fPicture != nil )
  3512.     {
  3513.     int zoomFactor;
  3514.     Point pictureOffset;
  3515.     Rect pictureRect;
  3516.     PicHandle thePicture;
  3517.     
  3518.     thePicture = (PicHandle)fPicture;
  3519.     pictureRect = (*thePicture)->picFrame;
  3520.     zoomFactor = framePartInfo->zoomFactor;
  3521.     pictureOffset = framePartInfo->pictureOffset;
  3522.     // normalisation
  3523.     ::OffsetRect( &pictureRect, -pictureRect.left, -pictureRect.top );
  3524.     // zoom
  3525.     if( zoomFactor > 0 )
  3526.         {
  3527.         pictureRect.right <<= zoomFactor;
  3528.         pictureRect.bottom <<= zoomFactor;
  3529.         }
  3530.     else
  3531.         {
  3532.         pictureRect.right >>= -zoomFactor;
  3533.         pictureRect.bottom >>= -zoomFactor;
  3534.         }
  3535.     // offset
  3536.     ::OffsetRect( &pictureRect, pictureOffset.h, pictureOffset.v );
  3537.     // stockage comme partie active
  3538.     framePartInfo->activeRect = pictureRect;
  3539.     }
  3540. return( framePartInfo->activeRect );
  3541. }
  3542.  
  3543. //====================================================================
  3544. // PictPartInfo
  3545. //====================================================================
  3546.  
  3547.  
  3548. PictPartInfoRec::PictPartInfoRec()
  3549. {
  3550. fIsActive = kODFalse;
  3551. fNeedsActivating = kODFalse; 
  3552. Initialize();
  3553. }
  3554.  
  3555. PictPartInfoRec::~PictPartInfoRec()
  3556. {
  3557. }
  3558.  
  3559. void PictPartInfoRec::Initialize()
  3560. {
  3561. pictureOffset.h = pictureOffset.v = 0;
  3562. zoomFactor = 0;
  3563. activeRect.left = 0;
  3564. activeRect.right = 0;
  3565. activeRect.top = 0;
  3566. activeRect.bottom = 0;
  3567. }
  3568.  
  3569.  
  3570. void PictPartInfoRec::ZoomIn()
  3571. {
  3572. if( IsZoomingInAllowed() )
  3573.     zoomFactor++;
  3574. }
  3575.  
  3576. void PictPartInfoRec::ZoomOut()
  3577. {
  3578. if( IsZoomingOutAllowed() )
  3579.     zoomFactor--;
  3580. }
  3581.  
  3582. ODBoolean PictPartInfoRec::IsZoomingInAllowed()
  3583. {
  3584. return( zoomFactor < 2 );
  3585. }
  3586.  
  3587. ODBoolean PictPartInfoRec::IsZoomingOutAllowed()
  3588. {
  3589. return( zoomFactor > -2 );
  3590. }
  3591.  
  3592.  
  3593.